package com.hfkj.channel.weixin.utils;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import org.apache.http.HttpHost;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.*;
import java.lang.annotation.Target;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Base64;

/**
 * http客户端
 * @className: HttpClientBuilder
 * @author: HuRui
 * @date: 2022/11/17
 **/
public class HttpClientBuilder {

    // 商户号
    private static final String merchantId = "1289663601";
    // 商户证书序列号
    private static final String merchantSerialNumber = "2FE142A25861D7AFD35CDAA9FC5598E1F93DA284";
    // 商户私钥
    private static final String privateKeyPath = "/home/project/wx_cert/1289663601_apiclient_key.pem";

    // 微信支付平台证书
    private static final String certificatePath = "/home/project/wx_cert/1289663601_apiclient_cert.pem";
    private static final String certificatePath2 = "/home/project/wx_cert/5BF2D8140449C61648DA5D5097DA28C066E6F7D4.pem";

    private CloseableHttpClient httpClient;

    private void build() throws FileNotFoundException {
        // 商户私钥
        PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new FileInputStream(privateKeyPath));

        // 微信平台证书
        X509Certificate wechatPayCert = PemUtil.loadCertificate(new FileInputStream(certificatePath));
        X509Certificate wechatPayCert2 = PemUtil.loadCertificate(new FileInputStream(certificatePath2));

        ArrayList<X509Certificate> wechatPayCertificates = new ArrayList<>();
        wechatPayCertificates.add(wechatPayCert);
        wechatPayCertificates.add(wechatPayCert2);

        // 通过WechatPayHttpClientBuilder构造的HttpClient，会自动的处理签名和验签
        httpClient = WechatPayHttpClientBuilder.create()
                .withMerchant(merchantId, merchantSerialNumber, merchantPrivateKey)
                .withWechatPay(wechatPayCertificates)
                .build();
    }

    /**
     * 获取请求
     * @return
     * @throws IOException
     */
    public CloseableHttpClient getHttpClient() throws IOException {
        if (httpClient == null) {
            build();
        }
        return httpClient;
    }

    /**
     * 获取证书列表
     * @return
     * @throws IOException
     * @throws URISyntaxException
     */
    public String getCertificate() throws IOException, URISyntaxException {
            getHttpClient();
            URIBuilder uriBuilder = new URIBuilder("https://api.mch.weixin.qq.com/v3/certificates");
            HttpGet httpGet = new HttpGet(uriBuilder.build());
            httpGet.addHeader("Accept", "application/json");
            CloseableHttpResponse response = httpClient.execute(httpGet);
            String bodyAsString = EntityUtils.toString(response.getEntity());
            System.out.println(bodyAsString);
            return bodyAsString;
    }

    /**
     * 申请商户
     * @return
     * @throws IOException
     * @throws URISyntaxException
     */
    public String applyment(JSONObject param) throws IOException {
        getHttpClient();
        HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/applyment4sub/applyment/");
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Content-type","application/json; charset=utf-8");
        httpPost.addHeader("Wechatpay-Serial", "5BF2D8140449C61648DA5D5097DA28C066E6F7D4");

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectMapper objectMapper = new ObjectMapper();

        objectMapper.writeValue(bos, param);
        httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));
        CloseableHttpResponse response = httpClient.execute(httpPost);
        String bodyAsString = EntityUtils.toString(response.getEntity());
        System.out.println(bodyAsString);
        return bodyAsString;
    }

    /**
     * 查询申请状态
     * @return
     * @throws IOException
     * @throws URISyntaxException
     */
    public String getApplyment(String applymentId) throws IOException {
        getHttpClient();
        HttpGet httpGet = new HttpGet("https://api.mch.weixin.qq.com/v3/applyment4sub/applyment/business_code/" + applymentId);
        httpGet.addHeader("Accept", "application/json");

        CloseableHttpResponse response = httpClient.execute(httpGet);

        String bodyAsString = EntityUtils.toString(response.getEntity());
        System.out.println(bodyAsString);
        return bodyAsString;
    }

    /**
     * 加密敏感信息
     * @param message
     * @return
     * @throws IllegalBlockSizeException
     * @throws IOException
     */
    public static String rsaEncryptOAEP(String message) throws IllegalBlockSizeException, IOException {
        try {
            Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
            cipher.init(Cipher.ENCRYPT_MODE, PemUtil.loadCertificate(new FileInputStream(certificatePath2)));
            byte[] data = message.getBytes("utf-8");
            byte[] cipherdata = cipher.doFinal(data);
            return Base64.getEncoder().encodeToString(cipherdata);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            throw new RuntimeException("当前Java环境不支持RSA v1.5/OAEP", e);
        } catch (InvalidKeyException e) {
            throw new IllegalArgumentException("无效的证书", e);
        } catch (IllegalBlockSizeException | BadPaddingException e) {
            throw new IllegalBlockSizeException("加密原串的长度不能超过214字节");
        }
    }



}
