package com.jeequan.jeepay.thirdparty.device.speaker.jsdSpeaker;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.jeequan.jeepay.core.constants.CS;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.device.JsdParams;
import com.jeequan.jeepay.core.model.device.PayOrderInfo4Device;
import com.jeequan.jeepay.core.utils.AmountUtil;
import com.jeequan.jeepay.core.utils.JeepayKit;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.Base64Utils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.util.TreeMap;

/**
 * @Author: ZhuXiao
 * @Description:
 * @Date: 18:20 2021/7/6
*/
@Slf4j
public class JsdUtil {

    /**
     * 发起get请求
     */
    public static JSONObject post(String reqUrl, JsdParams jsdParams, JSONObject reqParams) throws BizException {

        packageCommonParams(jsdParams, reqParams);

        // 发起请求
        log.info("金士盾设备号：{}，请求地址：{}，请求参数：{}", jsdParams.getDeviceParams().getDeviceNo(), reqUrl, reqParams.toJSONString());
        String responseStr = HttpUtil.createPost(reqUrl)
                .header("accessKey", jsdParams.getProviderParams().getAccessKey())
                .body(reqParams.toJSONString())
                .timeout(60000)
                .execute().body();
        log.info("金士盾设备号：{}，返回结果：{}", jsdParams.getDeviceParams().getDeviceNo(), responseStr);

        if (StringUtils.isBlank(responseStr)) {
            throw new BizException("请求失败");
        }

        return JSONObject.parseObject(responseStr);
    }

    /** 获取播报内容    */
    public static JSONObject getSpeakData(String customContent, PayOrderInfo4Device payOrderInfo) {
        JSONObject voiceJson = new JSONObject();

        // 订单号
        voiceJson.put("orderNo", payOrderInfo.getPayOrderId());
        // 请求唯一值
        voiceJson.put("requestId", payOrderInfo.getPayOrderId());
        // 金额
        voiceJson.put("money", AmountUtil.convertCent2DollarShort(payOrderInfo.getAmount()+""));


        // 防逃单播报走自定义模式
        if (PayOrderInfo4Device.BOARD_TYPE_CANCEL.equals(payOrderInfo.getWayCodeType())) {
            voiceJson.put("payType", "4");
            voiceJson.put("msg", "客户取消付款" + AmountUtil.convertCent2DollarShort(payOrderInfo.getAmount()+"") + "元");
            return voiceJson;
        }

        // 会员余额支付
        if (PayOrderInfo4Device.BOARD_TYPE_MEMBER.equals(payOrderInfo.getWayCodeType())) {
            voiceJson.put("payType", "4");
            voiceJson.put("msg", "会员支付" + AmountUtil.convertCent2DollarShort(payOrderInfo.getAmount()+"") + "元");
            return voiceJson;
        }

        // 配置了自定义播报内容
        if (StringUtils.isNotBlank(customContent)) {
            voiceJson.put("payType", "4");
            voiceJson.put("msg", customContent + AmountUtil.convertCent2DollarShort(payOrderInfo.getAmount()+"")+ "元");
        }else {
            // 未配置 自定义播报内容，走默认播报语音
            voiceJson.put("payType", "4");
            voiceJson.put("msg", getPayContent(payOrderInfo.getWayCodeType(), payOrderInfo.getAmount()));
        }

        return voiceJson;
    }

    private static JSONObject packageCommonParams(JsdParams jsdParams, JSONObject reqParams) {
        reqParams.put("deviceName", jsdParams.getDeviceParams().getDeviceNo());  //设备名称  唯一
        reqParams.put("sign", getSign(reqParams, jsdParams.getProviderParams().getAccessKeySecret()));

        return reqParams;
    }

    /**
     * 生成签名字符串
     */
    public static String getSign(JSONObject params, String appSecret) throws BizException {

        TreeMap<String, Object> tree = new TreeMap<>();

        // 1. 所有参数进行排序
        params.keySet().forEach(key -> {
            if (!"sign".equals(key) && StringUtils.isNotEmpty(params.get(key).toString())) {
                tree.put(key, params.get(key));
            }
        });

        //2. 拼接为 key=value&形式
        String signStr = JeepayKit.genUrlParams(tree);

        //3. 拼接appSecret
        log.info("金士盾【待加签字符串】：{}", signStr);
        return generateHmacSHA256(signStr, appSecret);
    }

    public static String generateHmacSHA256(String data, String key) {
        String result = null;
        try {
            SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(secretKey);
            result = Base64Utils.encodeToString(mac.doFinal(data.getBytes(StandardCharsets.UTF_8)));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 支付方式
     */
    public static String getPayContent(String wayCodeType, Long amount) {

        // 分转元
        String amountStr = AmountUtil.convertCent2DollarShort(amount+"")+ "元";

        if (CS.PAY_WAY_CODE_TYPE.WECHAT.equals(wayCodeType)) { // 微信
            return "微信收款" + amountStr;
        }else if (CS.PAY_WAY_CODE_TYPE.ALIPAY.equals(wayCodeType)) { // 支付宝
            return "支付宝收款" + amountStr;
        }else if (CS.PAY_WAY_CODE_TYPE.YSFPAY.equals(wayCodeType)) { // 云闪付
            return "云闪付收款" + amountStr;
        }else {
            return "收款" + amountStr;
        }
    }

    /** 金额转元，并去掉多余0 */
    public static String covertMoney(Long amount) {
        return new BigDecimal(String.valueOf(amount)).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString();
    }

}
