package com.liquidnet.service.dragon.utils;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.internal.util.file.IOUtils;
import com.liquidnet.commons.lang.util.MD5Utils;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.net.ssl.SSLContext;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.util.*;

public class PayDouYinpayUtils {
    private CloseableHttpClient httpClient;
    private static PayDouYinpayUtils instance = new PayDouYinpayUtils();

    private final String merchantId = "1551961491";
    private final String partnerKey = "itIuO65O9yKmemOu3S8g1S4orqvCGwXK";

    private final String SALT = "D3rXySlTCR15LxYnmbEOaamGoOCbBNQAbFtaK39t";
    private final String APP_ID="tt0d647bd9925c076801";


    public static String md5FromStr(String inStr) {
        MessageDigest md5;
        try {
            md5 = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return "";
        }

        byte[] byteArray = inStr.getBytes(StandardCharsets.UTF_8);
        byte[] md5Bytes = md5.digest(byteArray);
        StringBuilder hexValue = new StringBuilder();
        for (byte md5Byte : md5Bytes) {
            int val = ((int) md5Byte) & 0xff;
            if (val < 16) {
                hexValue.append("0");
            }
            hexValue.append(Integer.toHexString(val));
        }
        return hexValue.toString();
    }
    public String createSign(Map<String, Object> paramsMap) {
        List<String> paramsArr = new ArrayList<>();
        for (Map.Entry<String, Object> entry : paramsMap.entrySet()) {
            String key = entry.getKey();
            if (key.equals("other_settle_params")) {
                continue;
            }
            String value = entry.getValue().toString();

            value = value.trim();
            if (value.startsWith("\"") && value.endsWith("\"") && value.length() > 1) {
                value = value.substring(1, value.length() - 1);
            }
            value = value.trim();
            if (value.equals("") || value.equals("null")) {
                continue;
            }
            switch (key) {
                case "app_id":
                case "thirdparty_id":
                case "sign":
                    break;
                default:
                    paramsArr.add(value);
                    break;
            }
        }
        paramsArr.add(SALT);
        Collections.sort(paramsArr);
        StringBuilder signStr = new StringBuilder();
        String sep = "";
        for (String s : paramsArr) {
            signStr.append(sep).append(s);
            sep = "&";
        }
        return md5FromStr(signStr.toString());
    }
    public PayDouYinpayUtils() {
    }

    public static PayDouYinpayUtils getInstance() {
        return instance;
    }


    public String getAPP_ID() {
        return APP_ID;
    }

    public String getMerchantId() {
        return merchantId;
    }

    public CloseableHttpClient getHttpClient() {
        try {
            if (httpClient == null) {
                InputStream certStream = PayDouYinpayUtils.class.getClassLoader().getResourceAsStream("payCert/wepay/wepay_apiclient_cert.p12");
                byte[] certData = IOUtils.toByteArray(certStream);
                certStream.read(certData);
                certStream.close();

                KeyStore keyStore = KeyStore.getInstance("PKCS12");
                ByteArrayInputStream inputStream = new ByteArrayInputStream(certData);
                try {
                    keyStore.load(inputStream, merchantId.toCharArray());
                } finally {
                    inputStream.close();
                }
                SSLContext sslcontext = SSLContexts.custom()
                        .loadKeyMaterial(keyStore, merchantId.toCharArray())
                        .build();
                SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                        sslcontext,
                        SSLConnectionSocketFactory.getDefaultHostnameVerifier());
                httpClient = HttpClients.custom()
                        .setSSLSocketFactory(sslsf)
                        .build();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return httpClient;
    }

    public static JSONObject getJsonObject(HttpServletRequest request) {
        String param= null;
        JSONObject jsonObject=null;
        try {
            BufferedReader streamReader = new BufferedReader( new InputStreamReader(request.getInputStream(), "UTF-8"));
            StringBuilder responseStrBuilder = new StringBuilder();
            String inputStr;
            while ((inputStr = streamReader.readLine()) != null)
                responseStrBuilder.append(inputStr);
            jsonObject = JSONObject.parseObject(responseStrBuilder.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return jsonObject;
    }

    public String createSign(SortedMap<String, Object> parameters) {
        StringBuffer sb = new StringBuffer();
        Set es = parameters.entrySet();//所有参与传参的参数按照accsii排序（升序）
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            Object v = entry.getValue();
            if (null != v && !"".equals(v)
                    && !"sign".equals(k) && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + partnerKey);
        return MD5Utils.md5(sb.toString()).toUpperCase();
    }

    public String getRequestXml(SortedMap<String, Object> parameters) {
        StringBuffer sb = new StringBuffer();
        sb.append("<xml>");
        Set es = parameters.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k) || "sign".equalsIgnoreCase(k)) {
                sb.append("<" + k + ">" + "<![CDATA[" + v + "]]></" + k + ">");
            } else {
                sb.append("<" + k + ">" + v + "</" + k + ">");
            }
        }
        sb.append("</xml>");
        return sb.toString();
    }

    public String unCodeReqInfo(String reqInfo) {
        try {
            Cipher cipher ;
            String key = MD5Utils.md5(partnerKey);
            SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "AES");
            Security.addProvider(new BouncyCastleProvider());

            cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);

            Base64.Decoder decoder = Base64.getDecoder();
            byte[] base64ByteArr = decoder.decode(reqInfo);
            String result = new String(cipher.doFinal(base64ByteArr));
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    @SuppressWarnings("unchecked")
    public static Map<String, String> parseXml(InputStream inputStream) throws Exception {

        if (inputStream == null) {
            return null;
        }

        Map<String, String> map = new HashMap<String, String>();// 将解析结果存储在HashMap中
        SAXReader reader = new SAXReader();// 读取输入流
        Document document = reader.read(inputStream);
        Element root = document.getRootElement();// 得到xml根元素
        List<Element> elementList = root.elements();// 得到根元素的所有子节点
        for (Element e : elementList) { // 遍历所有子节点
            map.put(e.getName(), e.getText());
        }

        inputStream.close(); // 释放资源
        inputStream = null;

        return map;
    }

    public String getPartnerKey() {
        return this.partnerKey;
    }

    public boolean notifySign(String sign, JSONObject jsonObject) {
        Map<String, Object> map = new HashMap<>();
        //循环转换
        for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
            map.put(entry.getKey(), entry.getValue());
        }
        String signBack=PayDouYinpayUtils.getInstance().createSign(map);
        if(sign.equals(signBack))
            return true;
        else
            return false;
    }

    public static String getStringByStringMap(Map<String, String> map) {
        SortedMap<String, Object> smap = new TreeMap<String, Object>(map);
        StringBuffer sb = new StringBuffer();
        for (Map.Entry<String, Object> m : smap.entrySet()) {
            sb.append(m.getKey()).append("=").append(m.getValue()).append("&");
        }
        sb.delete(sb.length() - 1, sb.length());
        return sb.toString();
    }

    public static void main(String[] args) {
        SortedMap<String, Object> paramMap = new TreeMap<String, Object>();
        paramMap.put("appid", "wx86f9777acf2cb585");
        paramMap.put("partnerid", "1551961491");
        paramMap.put("prepayid", "wx26131443671359787bb3996a1fa0fc0000");
        paramMap.put("package", "Sign=WXPay");
        paramMap.put("noncestr", "rGcsOnNdZ4d9zu6k3yCbVJRG8Ombp8VW");
        paramMap.put("timestamp", "1627276483");
        String sign = PayDouYinpayUtils.getInstance().createSign(paramMap);
        System.out.println("1627274771===="+sign);
    }
}
