package com.sqx.modules.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sqx.modules.common.service.CommonInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import sun.misc.BASE64Encoder;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;

@Component
@Slf4j
public class VerifyIdCardUtils {
    // 这里使用静态，让 service 属于类
    private static CommonInfoService commonInfoService;

    // 注入的时候，给类的 service 注入
    @Autowired
    public void setWxChatContentService(CommonInfoService commonInfoService) {
        VerifyIdCardUtils.commonInfoService = commonInfoService;
    }


    /**
     * 验证身份信息
     * @param cardNo  身份证号
     * @param realName  姓名
     * @return
     */
    public static String verifyIdCard(String cardNo,String realName) {
        try{
            //云市场分配的密钥Id
            String secretId = commonInfoService.findOne(257).getValue();
            //云市场分配的密钥Key
            String secretKey = commonInfoService.findOne(258).getValue();
            String source = commonInfoService.findOne(259).getValue();

            Calendar cd = Calendar.getInstance();
            SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
            sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
            String datetime = sdf.format(cd.getTime());
            // 签名
            String auth = calcAuthorization(source, secretId, secretKey, datetime);
            // 请求方法
            String method = "GET";
            // 请求头
            Map<String, String> headers = new HashMap<String, String>();
            headers.put("X-Source", source);
            headers.put("X-Date", datetime);
            headers.put("Authorization", auth);

            // 查询参数
            Map<String, String> queryParams = new HashMap<String, String>();
            queryParams.put("cardNo",cardNo);
            queryParams.put("realName",realName);
            // body参数
            Map<String, String> bodyParams = new HashMap<String, String>();

            // url参数拼接
            String url = "https://service-hcgajsa5-1253495967.ap-beijing.apigateway.myqcloud.com/release/idcard/VerifyIdcardv2";
            if (!queryParams.isEmpty()) {
                url += "?" + urlencode(queryParams);
            }

            BufferedReader in = null;
            try {
                URL realUrl = new URL(url);
                HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
                conn.setConnectTimeout(5000);
                conn.setReadTimeout(5000);
                conn.setRequestMethod(method);

                // request headers
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    conn.setRequestProperty(entry.getKey(), entry.getValue());
                }

                // request body
                Map<String, Boolean> methods = new HashMap<>();
                methods.put("POST", true);
                methods.put("PUT", true);
                methods.put("PATCH", true);
                Boolean hasBody = methods.get(method);
                if (hasBody != null) {
                    conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

                    conn.setDoOutput(true);
                    DataOutputStream out = new DataOutputStream(conn.getOutputStream());
                    out.writeBytes(urlencode(bodyParams));
                    out.flush();
                    out.close();
                }

                // 定义 BufferedReader输入流来读取URL的响应
                in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                String line;
                String result = "";
                while ((line = in.readLine()) != null) {
                    result += line;
                }
                JSONObject res = JSON.parseObject(result);
                String errorCode = res.getString("error_code");
                if("0".equals(errorCode)){
                    JSONObject result1 = res.getJSONObject("result");
                    String isok = result1.getString("isok");
                    if("true".equals(isok)){
                        return "ok";
                    }
                }
                log.error("身份验证失败:"+res.getString("reason"));
            } catch (Exception e) {
                e.printStackTrace();
                log.error("身份验证网络请求失败！"+e.getMessage(),e);
            } finally {
                try {
                    if (in != null) {
                        in.close();
                    }
                } catch (Exception e2) {
                    e2.printStackTrace();
                    log.error("身份验证io流关闭失败！"+e2.getMessage(),e2);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("身份验证失败！"+e.getMessage(),e);
        }
        return "身份验证失败，请检查后重试！";
    }






    public static String calcAuthorization(String source, String secretId, String secretKey, String datetime)
            throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException {
        String signStr = "x-date: " + datetime + "\n" + "x-source: " + source;
        Mac mac = Mac.getInstance("HmacSHA1");
        Key sKey = new SecretKeySpec(secretKey.getBytes("UTF-8"), mac.getAlgorithm());
        mac.init(sKey);
        byte[] hash = mac.doFinal(signStr.getBytes("UTF-8"));
        String sig = new BASE64Encoder().encode(hash);

        String auth = "hmac id=\"" + secretId + "\", algorithm=\"hmac-sha1\", headers=\"x-date x-source\", signature=\"" + sig + "\"";
        return auth;
    }

    public static String urlencode(Map<?, ?> map) throws UnsupportedEncodingException {
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<?, ?> entry : map.entrySet()) {
            if (sb.length() > 0) {
                sb.append("&");
            }
            sb.append(String.format("%s=%s",
                    URLEncoder.encode(entry.getKey().toString(), "UTF-8"),
                    URLEncoder.encode(entry.getValue().toString(), "UTF-8")
            ));
        }
        return sb.toString();
    }




}
