package com.liquidnet.service.dragon.utils;

import com.alipay.api.internal.util.file.IOUtils;
import com.liquidnet.commons.lang.util.MD5Utils;
import com.liquidnet.service.dragon.channel.wepay.resp.WePayRefundReturnDto;
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.DocumentException;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.net.ssl.SSLContext;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.Security;
import java.util.*;

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

    private final String merchantId = "1551961491";
    private final String appId = "wx3498304dda39c5a1";
    private final String parentKey = "itIuO65O9yKmemOu3S8g1S4orqvCGwXK";


    public PayWepayUtils() {
    }

    public static PayWepayUtils getInstance() {
        return instance;
    }


    public String getAppId() {
        return appId;
    }

    public String getMerchantId() {
        return merchantId;
    }

    public CloseableHttpClient getHttpClient() {
        try {
            if (httpClient == null) {
                InputStream certStream = PayWepayUtils.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;
    }

    //生成随机字符串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 String createSign(SortedMap<Object, 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=" + parentKey);
        return MD5Utils.md5(sb.toString()).toUpperCase();
    }

    public String getRequestXml(SortedMap<Object, 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(parentKey);
            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 "";
        }
    }
}
