package com.hai.config;

import com.alibaba.fastjson.JSONObject;
import com.hai.common.pay.util.sdk.WXPayConstants;
import com.hai.common.utils.HttpsUtils;
import com.hai.common.utils.MD5Util;
import com.hai.dao.HighPayRecordMapper;
import com.hai.entity.HighPayRecord;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

/**
 * 银联支付
 * @author hurui
 */
@Component
public class UnionPayConfig {

    @Resource
    private HighPayRecordMapper highPayRecordMapper;

    // 重庆惠昕石化有限责任公司
    public final static String MER_ID1 = "83169055983W000";
    public final static String TERM_ID1 = "XS000103";

    // 重庆惠兑电子商务有限公司
    public final static String MER_ID2 = "83169054816W999";
    public final static String TERM_ID2 = "XS000104";

    // 个体户黎杨珍
    public final static String MER_ID3 = "83169054816W998";
    public final static String TERM_ID3 = "XS000105";

    /**
     * 【注意】请勿随意调用，会更新签名秘钥。会导致接口签名错误
     * 更新并获取签名密钥
     * 文档地址： https://doc.eycard.cn/web/#/42?page_id=542
     * @return 响应信息
     * @throws Exception
     */
    private static JSONObject getSign() throws Exception {
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("channelid", CommonSysConst.getSysConfig().getUnionPayChannelid());
        paramMap.put("opt", "getSign");
        return HttpsUtils.doPostForm(CommonSysConst.getSysConfig().getUnionPayUrl(), generateRequestParam(paramMap), new HashMap<>());
    }

    /**
     * APP控件支付
     * 文档地址： https://doc.eycard.cn/web/#/42?page_id=1516
     * @param orderNo  订单号
     * @param payPrice  支付金额 【单位：分】
     * @param orderDesc  订单描述 或 商品描述；例如：购买中石化加油券300元。
     * @return 响应信息
     * @throws Exception
     */
    public JSONObject upPreOrder(String merId, String termId, String orderNo, BigDecimal payPrice, String orderDesc, String notifyUrl, HttpServletRequest request) throws Exception {
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("channelid", CommonSysConst.getSysConfig().getUnionPayChannelid());
        paramMap.put("merid", merId);
        paramMap.put("termid", termId);
        paramMap.put("tradetrace", orderNo);
        paramMap.put("opt", "upPreOrder");
        paramMap.put("tradetype", "APP");
        paramMap.put("tradeamt", payPrice.multiply(new BigDecimal("100")).intValue());
        paramMap.put("body", orderDesc);
        paramMap.put("notifyurl", notifyUrl);

        String requestParam = generateRequestParam(paramMap);

        // 记录请求参数
        HighPayRecord payRecord = new HighPayRecord();
        payRecord.setCreateTime(new Date());
        payRecord.setPaySerialNo(orderNo);
        payRecord.setResType(1);
        payRecord.setPayType(3);
        payRecord.setPayMoney(payPrice);
        payRecord.setBodyInfo(requestParam);
        highPayRecordMapper.insert(payRecord);

        JSONObject responseParam = HttpsUtils.doPostForm(CommonSysConst.getSysConfig().getUnionPayUrl(), requestParam, new HashMap<>());

        // 记录响应参数
        payRecord = new HighPayRecord();
        payRecord.setCreateTime(new Date());
        payRecord.setPaySerialNo(orderNo);
        payRecord.setResType(3);
        payRecord.setPayType(3);
        payRecord.setPayMoney(payPrice);
        payRecord.setBodyInfo(responseParam.toString());
        highPayRecordMapper.insert(payRecord);

        return responseParam;
    }

    /**
     * 交易查询
     * @param paySerialNo 第三方支付流水
     * @return
     * @throws Exception
     */
    public static JSONObject tradeQuery(String merId,String termId,String paySerialNo) throws Exception {
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("channelid", CommonSysConst.getSysConfig().getUnionPayChannelid());
        paramMap.put("merid", merId);
        paramMap.put("termid", termId);
        paramMap.put("tradetrace", paySerialNo);
        paramMap.put("opt", "tradeQuery");
        return HttpsUtils.doPostForm(CommonSysConst.getSysConfig().getUnionPayUrl(), generateRequestParam(paramMap), new HashMap<>());
    }


    /**
     * 交易退货
     * @param orderNo 订单号
     * @param paySerialNo  第三方订单号
     * @param refundPrice  退款金额
     * @return
     * @throws Exception
     */
    public static JSONObject zwrefund(String merId,String termId,String orderNo,String paySerialNo,Long refundPrice) throws Exception {
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("channelid", CommonSysConst.getSysConfig().getUnionPayChannelid());
        paramMap.put("merid", merId);
        paramMap.put("termid", termId);
        paramMap.put("tradetrace", orderNo);
        paramMap.put("oriwtorderid", paySerialNo);
        paramMap.put("tradeamt", refundPrice);
        paramMap.put("opt", "zwrefund");
        return HttpsUtils.doPostForm(CommonSysConst.getSysConfig().getUnionPayUrl(), generateRequestParam(paramMap), new HashMap<>());
    }

    /**
     * 交易撤销
     * @param orderNo 订单号
     * @param paySerialNo  第三方订单号
     * @return
     * @throws Exception
     */
    public static JSONObject cancel(String merId,String termId,String orderNo,String paySerialNo) throws Exception {
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("channelid", CommonSysConst.getSysConfig().getUnionPayChannelid());
        paramMap.put("merid", merId);
        paramMap.put("termid", termId);
        paramMap.put("tradetrace", orderNo);
        paramMap.put("oriwtorderid", paySerialNo);
        paramMap.put("opt", "cancel");
        return HttpsUtils.doPostForm(CommonSysConst.getSysConfig().getUnionPayUrl(), generateRequestParam(paramMap), new HashMap<>());
    }

    /**
     * 参数排序
     * @param param
     * @return
     */
    private static String paramSort(final Map<String, Object> param) {
        Set<String> keySet = param.keySet();
        String[] keyArray = keySet.toArray(new String[keySet.size()]);
        Arrays.sort(keyArray);
        StringBuilder sb = new StringBuilder();
        for (String k : keyArray) {
            if (k.equals(WXPayConstants.FIELD_SIGN)) {
                continue;
            }
            if (StringUtils.isBlank(sb.toString())) {
                sb.append(k).append("=").append(param.get(k));
            } else {
                sb.append("&").append(k).append("=").append(param.get(k));
            }
        }
        return sb.toString();
    }

    /**
     * 生成请求参数
     * @param data
     * @return
     * @throws Exception
     */
    private static String generateRequestParam(final Map<String, Object> data) throws Exception{
        String paramSort = paramSort(data);

        // 生产签名参数
        String signParam = paramSort;
        // 签名参数拼接签名秘钥
        signParam += "&key=" + CommonSysConst.getSysConfig().getUnionPaySignKey();

        // 请求参数拼接签名
        paramSort += "&sign=" + MD5Util.encode(signParam.getBytes());
        return paramSort;
    }

}
