package com.xinelu.framework.config;

import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import com.xinelu.common.config.XylWeChatPaymentConfig;
import com.xinelu.common.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;

/**
 * @Description 新医路商户号微信支付核心配置类
 * @Author 纪寒
 * @Date 2022-10-17 18:56:22
 * @Version 1.0
 */
@Configuration
@Slf4j
public class XylWeChatPaymentUtilConfig {

    @Resource
    private XylWeChatPaymentConfig xylWeChatPaymentConfig;

    /**
     * 获取新医路签名信息
     *
     * @return 签名信息
     * @throws Exception 异常信息
     */
    @Bean(name = "xylVerifier")
    public Verifier getXylVerifier() throws Exception {
        PrivateKey privateKey = getPrivateKey(xylWeChatPaymentConfig.getXylPrivateKeyPath());
        PrivateKeySigner privateKeySigner = new PrivateKeySigner(xylWeChatPaymentConfig.getXylMchSerialNo(), privateKey);
        WechatPay2Credentials wechatPay2Credentials = new WechatPay2Credentials(xylWeChatPaymentConfig.getXylMchId(), privateKeySigner);
        CertificatesManager certificatesManager = CertificatesManager.getInstance();
        certificatesManager.putMerchant(xylWeChatPaymentConfig.getXylMchId(), wechatPay2Credentials, xylWeChatPaymentConfig.getXylPaymentKey().getBytes(StandardCharsets.UTF_8));
        return certificatesManager.getVerifier(xylWeChatPaymentConfig.getXylMchId());
    }

    /**
     * 获取新医路商户号带有签名的http请求对象
     *
     * @return CloseableHttpClient对象
     */
    @Bean(name = "xinYiLuWeChatPayClient")
    public CloseableHttpClient getXinYiLuWeChatPayClient(Verifier xylVerifier) {
        PrivateKey privateKey = getPrivateKey(xylWeChatPaymentConfig.getXylPrivateKeyPath());
        CloseableHttpClient closeableHttpClient = null;
        try {
            closeableHttpClient = WechatPayHttpClientBuilder.create()
                    .withMerchant(xylWeChatPaymentConfig.getXylMchId(), xylWeChatPaymentConfig.getXylMchSerialNo(), privateKey)
                    .withValidator(new WechatPay2Validator(xylVerifier)).build();
        } catch (Exception e) {
            log.error("新医路验证签名信息失败，失败信息：{}", e.getMessage());
        }
        return closeableHttpClient;
    }

    /**
     * 获取新医路商户号无签名的http请求对象
     *
     * @return CloseableHttpClient对象
     */
    @Bean(name = "xinYiLuWeChatPayNoSignClient")
    public CloseableHttpClient getXinYiLuWeChatPayNoSignClient() {
        PrivateKey privateKey = getPrivateKey(xylWeChatPaymentConfig.getXylPrivateKeyPath());
        return WechatPayHttpClientBuilder.create()
                .withMerchant(xylWeChatPaymentConfig.getXylMchId(), xylWeChatPaymentConfig.getXylMchSerialNo(), privateKey)
                .withValidator((response) -> true).build();
    }

    /**
     * 获取商户的私钥文件
     *
     * @param filename 获取商户的私钥文件
     * @return 商户私钥
     */
    private PrivateKey getPrivateKey(String filename) {
        try {
            return PemUtil.loadPrivateKey(new ClassPathResource(filename).getInputStream());
        } catch (Exception e) {
            log.error("新医路商户私钥文件不存在，错误原因：{}", e.getMessage());
            throw new ServiceException("新医路商户私钥文件不存在，请联系管理员！");
        }
    }
}
