package com.liquidnet.service.dragon.utils;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.internal.util.file.IOUtils;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.liquidnet.commons.lang.util.MD5Utils;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
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 static PoolingHttpClientConnectionManager poolConnManager =null;

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


    private final String APP_ID="tt0d647bd9925c076801";
    private  final String TOKEN="NdUpRqpXmDfddigojFzIxzXNVg1SffdA";



    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());

                // 配置同时支持 HTTP 和 HTPPS
                Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create().register("http", PlainConnectionSocketFactory.getSocketFactory()).register("https", sslsf).build();
                // 初始化连接管理器
                poolConnManager =new PoolingHttpClientConnectionManager(socketFactoryRegistry);
                poolConnManager.setMaxTotal(4000);// 同时最多连接数
                // 设置最大路由
                poolConnManager.setDefaultMaxPerRoute(2000);

                // 初始化httpClient
                httpClient = getConnection();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return httpClient;
    }

    public static CloseableHttpClient getConnection() {
        RequestConfig config = RequestConfig.custom().setConnectTimeout(5000).setConnectionRequestTimeout(5000).setSocketTimeout(5000).build();
        CloseableHttpClient httpClient = HttpClients.custom()
                // 设置连接池管理
                .setConnectionManager(poolConnManager)
                .setDefaultRequestConfig(config)
                // 设置重试次数
                .setRetryHandler(new DefaultHttpRequestRetryHandler(2,false)).build();
        return httpClient;
    }

    //生成随机字符串nonce_str
    public String getNonceStr() {
        String base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 32; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

    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 String getPartnerKey() {
        return this.partnerKey;
    }

    public boolean notifySign(String sign, JSONObject jsonObject) throws Exception {
        jsonObject.remove("msg_signature");
        jsonObject.remove("type");
        jsonObject.put("token",TOKEN);
        SortedMap<String,String> sortedMap = new TreeMap<String,String>();
        for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
            sortedMap.put(entry.getValue().toString(), entry.getValue().toString());
        }
        StringBuffer sb = new StringBuffer();
        for(String key:sortedMap.keySet()){
            sb.append(sortedMap.get(key));
        }
        String signBack= DigestUtils.sha1Hex(sb.toString());
        //PayDouYinpayUtils.getInstance().createSign(map);
        if(sign.equals(signBack))
            return true;
        else
            return false;
    }
    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 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,String> sortedMap = new TreeMap<String,String>();
        sortedMap.put("timestamp","1602507471");
        sortedMap.put("nonce","797");
        sortedMap.put("msg","{\"appid\":\"tt07e3715e98c9aac0\",\"cp_orderno\":\"out_order_no_1\",\"cp_extra\":\"\",\"way\":\"2\",\"payment_order_no\":\"2021070722001450071438803941\",\"total_amount\":9980,\"status\":\"SUCCESS\",\"seller_uid\":\"69631798443938962290\",\"extra\":\"null\",\"item_id\":\"\"}");
        sortedMap.remove("msg_signature");
        sortedMap.remove("type");
        sortedMap.put("token","NdUpRqpXmDfddigojFzIxzXNVg1SffdA");
        StringBuffer sb = new StringBuffer();
        for(String key:sortedMap.keySet()){
            sb.append(sortedMap.get(key));
        }
        System.out.println(sortedMap.toString());
        System.out.println(sb.toString());

        String signBack= DigestUtils.sha1Hex(sb.toString());
        System.out.println(signBack);
    }
}
