package ink.wgink.module.wechat.manager.pay.v3;

import ink.wgink.exceptions.base.SystemException;
import ink.wgink.module.wechat.enums.PayAuthorizationTypeEnum;
import ink.wgink.module.wechat.service.pay.v3.certificates.ICertificateService;
import ink.wgink.module.wechat.utils.pay.PayCertificateUtil;
import ink.wgink.module.wechat.utils.pay.PaySignAuthorizationUtil;
import ink.wgink.properties.wechat.pay.v3.PayProperties;
import ink.wgink.util.UUIDUtil;
import ink.wgink.util.string.WStringUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.RequestMethod;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.security.cert.X509Certificate;

/**
 * 1.系统调用微信接口需要用商家证书认证
 * 2.系统接收微信回调参数时，需要平台证书，平台证书定期更新（每6小时），需要通过接口下载保存
 * 3.商家证书每次读取文件
 * 4.平台证书读取缓存
 *
 * @ClassName: PayMiniappManager
 * @Description: 支付管理
 * @Author: wanggeng
 * @Date: 2021/8/19 11:10 上午
 * @Version: 1.0
 */
public class PayManager {

    private static final PayManager PAY_MANAGER = PayMiniappManagerBuilder.payManager;
    private ICertificateService certificateService;
    private PayProperties payProperties;
    private X509Certificate platformCertificate;

    private PayManager() {
    }

    public static PayManager getInstance() {
        return PAY_MANAGER;
    }

    /**
     * 获取商户证书
     *
     * @return
     * @throws FileNotFoundException
     */
    public X509Certificate getBusinessCertificate() throws FileNotFoundException {
        return PayCertificateUtil.getCertificate(new FileInputStream(payProperties.getCertificatePath() + File.separator + payProperties.getCertificateName()));
    }

    /**
     * 获取平台证书
     *
     * @return
     * @throws FileNotFoundException
     */
    public X509Certificate getPlatformCertificate() {
        // 不存在读取默认证书
        if (platformCertificate == null) {
            throw new SystemException("平台证书为不存在");
        }
        return platformCertificate;
    }

    /**
     * 认证头
     *
     * @param requestMethod
     * @param urlSuffix
     * @param payProperties
     * @param jsonBody
     * @param payAuthorizationTypeEnum
     * @return
     * @throws FileNotFoundException
     */
    public String getAuthorization(RequestMethod requestMethod, String urlSuffix, String serialNumber, PayProperties payProperties, String jsonBody, PayAuthorizationTypeEnum payAuthorizationTypeEnum) throws Exception {
        String randomSubStr = WStringUtil.randomSubStr(UUIDUtil.get32UUID(), 10).toUpperCase();
        return PaySignAuthorizationUtil.buildAuthorization(requestMethod, urlSuffix,
                payProperties.getMchid(), serialNumber,
                payProperties.getKeyFilePath(), StringUtils.isBlank(jsonBody) ? "" : jsonBody, randomSubStr, System.currentTimeMillis() / 1000,
                payAuthorizationTypeEnum.getValue());
    }

    /**
     * 刷新证书
     */
    public void refreshPlatformCertificate() throws Exception {
        String newestCertificate = certificateService.getNewestPlatformCertificate();
        this.platformCertificate = PayCertificateUtil.getCertificate(new FileInputStream(newestCertificate));
    }

    public void setPayProperties(PayProperties payProperties) {
        this.payProperties = payProperties;
    }

    public void setCertificateService(ICertificateService certificateService) {
        this.certificateService = certificateService;
    }

    private static class PayMiniappManagerBuilder {
        public static PayManager payManager = new PayManager();
    }

}
