package com.jeesharp.business.modules.pay.paytype.pufapay;

import api.ApiResponse;
import api.SPDBSMEncryptor;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONUtil;
import cn.hutool.core.util.StrUtil;
import com.jeesharp.business.modules.pay.constant.PayMessage;
import com.jeesharp.business.modules.pay.dto.PfPayOrderData;
import com.jeesharp.business.modules.pay.enums.PayMessageConstants;
import com.jeesharp.business.modules.pay.paytype.pufapay.baseutil.RSASign;
import com.jeesharp.business.modules.pay.paytype.pufapay.config.PuFaPayConfig;
import com.jeesharp.business.modules.pay.paytype.pufapay.order.dto.*;
import com.jeesharp.business.modules.pay.util.PayCommonUtil;
import org.apache.http.HttpStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpMethod;

import java.lang.reflect.Field;
import java.math.BigDecimal;

/**
 * @Author: wangmeng
 * @CreateTime: 2023-10-16  18:17
 * @Description: 浦发支付相关方法
 */
public class PfPayUtils {
    private static Logger logger = LoggerFactory.getLogger(PfPayUtils.class);

    private static final String ORDER_LAST_PAY_TIME = "5m";//最后付款时间

    /**
     * 浦发下单模式，返回聚合支付二维码并且存储
     *
     * @param payOrderData
     * @return
     */
    public static AppPayTradeResp creatOrder(PfPayOrderData payOrderData) {
        AppPayTrade appPayTrade = getAppPayTrade(payOrderData);
        try {
            validRequestMessage(AppPayTrade.class, appPayTrade);//校验支付参数
            JSONConfig jsonConfig = new JSONConfig();
            jsonConfig.setIgnoreNullValue(false);
            String requestBody = JSONUtil.toJsonStr(appPayTrade, jsonConfig);//组装请求参数
            // 是否获取防重放参数
            Boolean forbidden = false;
            //是否是全报文
            Boolean encryption = true;
            ApiResponse apiResponse = SPDBSMEncryptor.requestApi(PuFaPayConfig.CLIENT_ID, PuFaPayConfig.SECRET, PuFaPayConfig.PRIVATE_KEY, PuFaPayConfig.SPDB_PUBLIC_KEY, HttpMethod.POST.name(), PuFaPayConfig.APP_PAY_TRADE, requestBody, forbidden, encryption);
            if (apiResponse.getCode() == HttpStatus.SC_OK) {
                String respStringXml = apiResponse.getDecryptBody();
                logger.info("响应解密报文:{}====验签：{}", respStringXml, apiResponse.getVerify());
                return JSONUtil.toBean(apiResponse.getDecryptBody(), AppPayTradeResp.class);
            }
        } catch (Exception e) {
            PayCommonUtil.wrapPayAndThrow("下单异常");
        }
        return null;
    }

    /**
     * 组装支付参数
     */
    private static AppPayTrade getAppPayTrade(PfPayOrderData payOrderData) {
        AppPayTrade appPayTrade = new AppPayTrade();
        appPayTrade.setCmdtyDsc(payOrderData.getSubject());//商品描述
        appPayTrade.setSpdbMrchNo(PuFaPayConfig.SPDB_MRC_NO);//商户号
        appPayTrade.setTranAmt(BigDecimal.valueOf(payOrderData.getPayAmount()).divide(new BigDecimal(100)).setScale(BigDecimal.ROUND_CEILING, BigDecimal.ROUND_HALF_UP).toString());//交易金额
        appPayTrade.setTerminalNo(PuFaPayConfig.TERMINAL_NO);//终端号
        appPayTrade.setLtstPyTm(ORDER_LAST_PAY_TIME);//订单最后付款时间。逾期自动关闭订单
        appPayTrade.setLtstPyTm1(ORDER_LAST_PAY_TIME);//二维码5分钟时效。逾期自动关闭订单
        appPayTrade.setPrblmNo(payOrderData.getStoreNumber());//门店编号
        appPayTrade.setTranType(payOrderData.getPfPayType());//交易类型
        appPayTrade.setMrchlInfmAdr(payOrderData.getNotifyUrl());//异步通知地址
        return appPayTrade;
    }

    /**
     * 验证报文数据
     *
     * @param cls
     * @param cls
     * @author wangmeng
     * @date 2023/5/17 17:19
     */
    public static void validRequestMessage(Class<? extends AppBaseReq> cls, AppBaseReq object) throws IllegalAccessException {
        Field[] fields = cls.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            Field field = fields[i];
            PayMessage ef = (PayMessage) field.getAnnotation(PayMessage.class);
            if (ef != null) {
                field.setAccessible(true);
                String value = (String) field.get(object);
                if (ef.maxLength() != 0) {//不等于0 时校验长度
                    if (StrUtil.isNotBlank(value)) {
                        if (value.length() > ef.maxLength()) {
                            PayCommonUtil.wrapPayExceptionAndThrow(PayMessageConstants.PAY_MESSAGE_LENGTH.getCode(), ef.value() + "【" + ef.name() + "】" + PayMessageConstants.PAY_MESSAGE_LENGTH.getMsg());
                        }
                    }
                }
                if (ef.must().equals("M") || ef.must().equals("Y")) {
                    if (StrUtil.isBlank(value)) {
                        PayCommonUtil.wrapPayExceptionAndThrow(PayMessageConstants.PAY_MESSAGE_LENGTH.getCode(), ef.value() + "【" + ef.name() + "】" + PayMessageConstants.PAY_MESSAGE_MUST.getMsg());
                    }
                }
            }
        }
    }

    /**
     * 浦发回调数据解密
     *
     * @param data 回调数据
     * @author wangmeng
     * @date 2023/11/14 16:15
     */
    public static AppNotifyResp decryptData(String data) {
        try {
            String decryptData = RSASign.decrypt(data);
            if (StrUtil.isNotBlank(decryptData)) {
                return JSONUtil.toBean(decryptData, AppNotifyResp.class);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        return null;
    }
}
