package com.jeequan.jeepay.thirdparty.channel.sybpay.kits;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.SignUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.crypto.asymmetric.Sign;
import cn.hutool.crypto.asymmetric.SignAlgorithm;
import cn.hutool.crypto.symmetric.AES;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.utils.StringKit;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.xml.bind.DatatypeConverter;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.UUID;

/**
 * TODO
 *
 * @author crystal
 * @date 2024/1/26 18:24
 */
@Slf4j
public class SybpayKits {

    public static final String TRANS_DOMAIN = "http://anquanfapay.shouyinbei.com/api/v1/transfer";

    public static final String TRANS_QUERY_DOMAIN = "http://anquanfapay.shouyinbei.com/api/v1/queryOrder";

    public static final String QUERY_BALANCE_DOMAIN = "http://anquanfapay.shouyinbei.com/api/v1/queryBalance";

    public static final String account_id = "50";

    public static final String mobile = "15062443898";

    public static final String SUCCESS_CODE = "1";

    public static final String BIZ_SUCCESS_CODE = "10000";

    public static final String PUB_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0DNaYHTLA6Y83miQaBggGjpVdSycumtbg6vq9EadM2gW5IPZ74DzQaw61K3hUnquFAcB2OYE0EDvnQYGLnabPPvJQ+/neZefe75IZ84kamxb6LFvi2MjFAr+AB2a+pPas0h3EOdQs/B/N6SIYZzGef3inEWxxi+/qzccIgyF5hVECadxm6qgpnyqfVW8HLCBjSjc74GPZ8xC/AovDxcycdUVcDrF0AHekkMxA8DkcWGcQ+IGFqjs0wPB7xlfcpG+1n1NWFUJXZX7tJpI8yv7GhxYmMGjHlmkEDijPflwqRGVQRrV+NyuoJCtlDExdfj8Z3sMlQ/rCeacsh98ONdKMwIDAQAB";

    public static final String PRI_KEY = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCaj1TK3w2h5lpIikqkTbxgxgqQcbjb3s6Sv8yhJ5i2qbPbcgy8h2W68+8pbtvDleRTLu9zP/BPjXcOF+kKPa8gOLFOdRtpzOQp3KlXxDTzsLC329bnyAwccr0O6rEmMj8hrPUznXXcA6jXYxLo2ICgu457ALfpwEz6qtUOYbRQSssVX+W5UPkqgYR+BnMGeCXvVoNA2k4SYixo1DXuI6IjZki3OuaX87BBoRiW2bIu3MxcgaYkq08PUeZtdOuJqI7I87vNXKO0Xu7JcA4cWQnKzjuUC9zTRj0ETDsxyQDsRmvJmJ9SUI33c0Q1v3OGnyko7TNVBPNKVLRgDQI9oKTvAgMBAAECggEAMVWk9CikmlQD53m0/6MMiTtNrfOO1SfWekMclygjd9LNZTOPWzJAx58LbQdEwLZ8rgyiRABZvZrjMK1zJmCwILHX7ro0qN3Myovzxd8MI+j3T4itnUhejUoWjMdfClkpi59AmVwefb7xSucF5ysMS8HyZdLB4awPJkgXP8LyIlpt+GHS6f5Mg/mkCpoG48FNdpjuPD9BTnEIHuZTNO5FpCrXbmuUAhoXjQHTOP0aDKYxYlMDS7XFoMcvjKI5gCaIWDmmmvmMaKngFHSETGQ6XQjIQ4ediUMAd5DHrzDqCi/WCGGbSvBf7z9TRKFW6shrYDxkRgReliFIrhffJ/M64QKBgQDXmEX2vH+Vq+bjSEti5fZ/XLEwQZ+GkcmyYr/GZcZMdhfSDoxc0boH9KQMhXFtQMlvmLIgrPKOs7Mb6nPP5UPyRhCytwso8MnlyHFQrtqamKyEMMoLtjJmwD2vGBxR5ugHXnnQFc0v9aurw8/mdr2M/dtpwALVNSloHCo0IeF13wKBgQC3hr9CzkA+WY8EFl1dhU5Md9Dkc61nImLFVdPLgggnR0/Qh3sZFNngmuayxZ2KFpEwlJ4GTA6LriEFOvbA1YCeC0BZkRW0vldJd8qJetnaUj3Y3b7ZMSQEvNPT7G/PhePtV9m1E+mgdlDfF/5dOTQs+xzknC8VZmqqvEYDTskS8QKBgQCTa3cjwT8IjBQEA/IwfQixjCNI2QaJEPU3OljiA8O1kua05ufJrEsll335ZeHqj+ttmJ7swvXU6EGn7Agm9yEf8BMI8Sr7YrLbodUCE549KfqFJYtyuLH8GqXTLYxn4Jl2OH7Y759vlPA/MlTdxQHV/9vhkr8dJQ3cN64QGb6+RwKBgHq3gUB8hXyrifPjuH6GWrrLC0UXDIX/+ieVok9cHXOWPYpkbS1yQdXr/gLgHN1vBZqEZb40MS25O58xtDlxCdWkFF1PpEH9XIRls2qGWRGhGHXgoHK+ZyU71jDI0mLjVmsn6Q0pyXhgZOcoNg/D5l2Fc+ZxgRJAL2cHCZHAprchAoGBAJRehV/N7zSJreY4+tf8lshKcoWuX9rKOakRLEK3UIHQwKBQj7x/CNvPbdslJ6kCgAhhLdztudWFgrcZT2eNs59d2OaT2lIhjzVdf9SPhQkrHoeNEeuO1gsIhWkgakt7wjGU5EsuwN00LCYaw+EZLhIbbpANP5Q44pgj1ebR1I3i";

    /**
     * 发起请求
     * @param url
     * @param bizData
     * @return
     */
    public static JSONObject reqApi(String url, JSONObject bizData) {
        bizData.put("mobile",mobile);
        bizData.put("account_id",account_id);
        bizData.put("pay_pwd",mobile);
        JSONObject reqData = new JSONObject();
        reqData.put("requestId", StringKit.getUUID());
        reqData.put("timestamp", DateUtil.format(new Date(), DatePattern.PURE_DATETIME_FORMAT));
        reqData.put("bizContent",bizData.toString());
        log.info("【安全发】接口加密前参数：{}",reqData);
        initSign(reqData);
        log.info("【安全发】接口请求参数：{}",reqData);
        String response = HttpUtil.post(url, reqData.toString());
        log.info("【安全发】接口返回参数:{}",response);
        if(StringUtils.isEmpty(response)){
            throw new BizException("转账接口异常");
        }
        JSONObject result = JSON.parseObject(response);
        if(!SUCCESS_CODE.equals(result.getString("code"))){
            throw new BizException(result.getString("msg"));
        }
        return result.getJSONObject("data");
    }

    /**
     * 初始化SIGN
     * @param reqData
     */
    private static void initSign(JSONObject reqData) {
        String bizContent = reqData.getString("bizContent");
        String randomKey = RandomUtil.randomString(16);
        AES aes = SecureUtil.aes(randomKey.getBytes(StandardCharsets.UTF_8));
        if (!bizContent.isEmpty()) {
            reqData.put("bizContent",aes.encryptBase64(bizContent));
        }
        RSA rsa = SecureUtil.rsa(PRI_KEY,PUB_KEY);
        reqData.put("check",rsa.encryptBase64(randomKey, KeyType.PublicKey));
        String signContent = "bizContent=" + reqData.getString("bizContent") + "&check="+reqData.getString("check") + "&requestId="+reqData.getString("requestId") + "&timestamp="+reqData.getString("timestamp");
        Sign sign = SecureUtil.sign(SignAlgorithm.SHA256withRSA, PRI_KEY,PUB_KEY);
        byte[] signByte  = sign.sign(signContent);
        reqData.put("sign",DatatypeConverter.printBase64Binary(signByte));
    }

    /**
     * 验证签名
     * @param params
     * @return
     */
    public static Boolean checkSign(JSONObject params) {
        Sign signUtil = SecureUtil.sign(SignAlgorithm.SHA256withRSA, null, PUB_KEY);
        String signContent = "bizContent=" + params.getString("bizContent") + "&check="+params.getString("check") + "&requestId="+params.getString("requestId") + "&timestamp="+params.getString("timestamp");
        return signUtil.verify(signContent.getBytes(StandardCharsets.UTF_8), DatatypeConverter.parseBase64Binary(params.getString("sign")));
    }

    /**
     * 解析回调参数
     * @param bizContent
     * @param check
     * @return
     */
    public static JSONObject analysisNotify(String bizContent,String check) {
        RSA rsa = SecureUtil.rsa(PRI_KEY,PUB_KEY);
        String randomKey = rsa.decryptStr(check, KeyType.PrivateKey);
        AES aes = SecureUtil.aes(randomKey.getBytes(StandardCharsets.UTF_8));
        return JSON.parseObject(aes.decryptStr(bizContent));
    }
}
