package org.jeecg.modules.pay.routing;

import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.pay.config.WechatPayV3Utils;
import org.jeecg.modules.pay.config.WechatUrlConstants;
import org.jeecg.modules.pay.entity.ReceiverAddForm;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.*;
import java.util.Base64;

@Slf4j
@Service
public class WeChatProfitSharingService {

    @Resource
    private WechatPayV3Utils wechatPayV3Utils;

    /**
     *  添加分账账号
     */
    public JSONObject receiversAdd(ReceiverAddForm receiverAddForm) throws Exception {
        ClassPathResource classPathResource = new ClassPathResource("cert/platform_cert.pem");
        InputStream certStream = classPathResource.getInputStream();
        X509Certificate x509Certificate = getCertificate(certStream);

        String name = rsaEncryptOAEP(receiverAddForm.getName(),x509Certificate);
        receiverAddForm.setName(name);
        JSONObject params = JSONObject.from(receiverAddForm);
        log.info("分账接收方:{}",receiverAddForm);
        JSONObject body = wechatPayV3Utils.profitSharingSendPost(WechatUrlConstants.PAY_V3_RECEIVERS_ADD,params);
        log.info("添加分账接收方结果:{}",body);
        return body;
    }

    /**
     * 获取证书
     *
     * @param inputStream 证书文件
     * @return {@link X509Certificate} 获取证书
     */
    public static X509Certificate getCertificate(InputStream inputStream) {
        try {
            CertificateFactory cf = CertificateFactory.getInstance("X509");
            X509Certificate cert = (X509Certificate) cf.generateCertificate(inputStream);
            cert.checkValidity();
            return cert;
        } catch (CertificateExpiredException e) {
            throw new RuntimeException("证书已过期", e);
        } catch (CertificateNotYetValidException e) {
            throw new RuntimeException("证书尚未生效", e);
        } catch (CertificateException e) {
            throw new RuntimeException("无效的证书", e);
        }
    }

    /**
     * 公钥加密   加密隐私信息数据
     *

     * @param certificate 平台公钥证书
     * @return 加密后的数据
     * @throws Exception 异常信息
     */
    public static String rsaEncryptOAEP(String message, X509Certificate certificate)
            throws IllegalBlockSizeException, IOException {
        try {
            Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
            cipher.init(Cipher.ENCRYPT_MODE, certificate.getPublicKey());
            byte[] data = message.getBytes(StandardCharsets.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字节");
        }
    }

}
