package com.hzs.third.pay.jdpay.util;

import com.google.gson.reflect.TypeToken;
import com.hzs.third.pay.jdpay.sdk.JdPayConstant;
import com.hzs.third.pay.jdpay.sdk.JdPayNewConfig;
import com.hzs.third.pay.jdpay.sdk.JdPaySecurity;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/*************************************************
 *
 * 京东支付接口工具类
 *
 *************************************************/
public class JdPayApiUtil {

    /**
     * 加密和签名
     */
    public static String encryptAndSignature(JdPayNewConfig jdPayNewConfig, String reqNo, String jsonParam) throws IOException {
        // 组装公共请求参数
        Map<String, String> commonParam = fillCommonParam(jdPayNewConfig.getMerchantNo(), reqNo);
        // 加密
        byte[] dataBytes = jsonParam.getBytes(StandardCharsets.UTF_8);
        JdPaySecurity se = new JdPaySecurity();
        String encData = se.signEnvelop(jdPayNewConfig.getPriCert(), jdPayNewConfig.getPriCertPwd(), jdPayNewConfig.getPubCert(), dataBytes);
        commonParam.put(JdPayConstant.ENC_DATA, encData);
        // 签名
        String sign = SignUtil.sign(commonParam, JdPayConstant.SHA256, jdPayNewConfig.getSignKey(), JdPayConstant.UTF8);
        commonParam.put(JdPayConstant.SIGN_DATA, sign);
        return GsonUtil.toJson(commonParam);
    }

    /**
     * 解密和验签
     */
    public static String decryptAndVerifySign(JdPayNewConfig jdPayNewConfig, String respText) throws Exception {
        Map<String, String> respMap = GsonUtil.fromJson(respText, new TypeToken<Map<String, String>>() {
        });
        String code = respMap.get(JdPayConstant.CODE);
        if (!JdPayConstant.SUCCESS_CODE.equals(code)) {
            return respText;
        }
        if (!respMap.containsKey(JdPayConstant.SIGN_DATA)) {
            throw new Exception(String.format("No sign field in response: %s", respText));
        }
        String sign = respMap.remove(JdPayConstant.SIGN_DATA);
        String signType = respMap.get(JdPayConstant.SIGN_TYPE);
        String charset = respMap.get(JdPayConstant.CHARSET);
        boolean isRespSignValid = SignUtil.verify(sign, respMap, signType, jdPayNewConfig.getSignKey(), charset);
        if (!isRespSignValid) {
            throw new Exception(String.format("Invalid sign value in response: %s", respText));
        }
        return SignUtil.decodeBase64(respMap.get(JdPayConstant.RESP_DATA), respMap.get(JdPayConstant.CHARSET), false, false);
    }

    /**
     * 组装api公共参数赋值
     */
    private static Map<String, String> fillCommonParam(String merchantNo, String reqNo) {

        Map<String, String> reqMap = new HashMap<>();
        // 二级商户号
        reqMap.put(JdPayConstant.MERCHANT_NO, merchantNo);
        //商户生成的唯一标识，可以与outTradeNo一致
        reqMap.put(JdPayConstant.REQ_NO, reqNo);
        //字符集
        reqMap.put(JdPayConstant.CHARSET, JdPayConstant.UTF8);
        //固定值
        reqMap.put(JdPayConstant.FORMAT_TYPE, JdPayConstant.JSON);
        //签名类型
        reqMap.put(JdPayConstant.SIGN_TYPE, JdPayConstant.SHA256);
        //固定值，证书加密
        reqMap.put(JdPayConstant.ENC_TYPE, JdPayConstant.AP7);
        return reqMap;
    }

}
