package com.ruoyi.common.pay.wx.util;

import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.pay.wx.config.WxPayConfig;
import com.ruoyi.common.pay.wx.domain.enums.WxNotifyEventType;
import com.ruoyi.common.utils.http.HttpUtils;
import com.wechat.pay.java.core.notification.Notification;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.payments.model.Transaction;

import javax.servlet.http.HttpServletRequest;

/**
 * @author wjh
 * 2024/8/12
 */
public class WxPayUtil {


    /**
     * 验签并解析
     */
    public static <T> T  checkAndParse(HttpServletRequest request, String body, Class<T> clazz, WxPayConfig config) {
        NotificationParser parser = config.notificationParser();

        // 构造 RequestParam
        RequestParam requestParam = new RequestParam.Builder()
                .serialNumber(request.getHeader("Wechatpay-Serial"))
                .nonce(request.getHeader("Wechatpay-Nonce"))
                .signature(request.getHeader("Wechatpay-Signature"))
                .timestamp(request.getHeader("Wechatpay-Timestamp"))
                .body(body)
                .build();
        // 验签
        return parser.parse(requestParam, clazz);
    }

    /**
     * 是否支付成功
     */
    public static boolean isSuccess(Transaction transaction) {
        return transaction != null && Transaction.TradeStateEnum.SUCCESS.equals(transaction.getTradeState());
    }

    /**
     * 验签并转为业务对象
     */
    public static Transaction toTransaction(HttpServletRequest request, WxPayConfig config) {
        // 获取原始报文body
        String body = HttpUtils.getBody(request);
        // 解析通知数据
        Notification notification = JSON.parseObject(body, Notification.class);
        // 支付成功通知
        if (WxNotifyEventType.TRANSACTION_SUCCESS.getValue().equals(notification.getEventType())) {
            // 验签、解密并转换成 Transaction
            return checkAndParse(request, body, Transaction.class, config);
        }
        return null;
    }


    public static String getTransferCLoseReason(String code) {
        switch (code) {
            case "OVERDUE_CLOSE": return "系统超时关闭，可能原因账户余额不足或其他错误";
            case "TRANSFER_SCENE_INVALID": return "付款确认时，转账场景已不可用，系统做关单处理";
            default: return "其他关闭原因";
        }
    }

    /**
     * 获取转账明细失败原因
     */
    public static String getTransferDetailErrorMsg(String code){
        switch (code){
            case "NAME_NOT_CORRECT":
                return "收款人姓名校验不通过，请核实信息";
            case "ACCOUNT_FROZEN":
                return "该用户账户被冻结";
            case "REAL_NAME_CHECK_FAIL":
                return "收款人未实名认证，需要用户完成微信实名认证";
            case "OPENID_INVALID":
                return "微信用户编号格式错误或者不属于商家公众账号";
            case "TRANSFER_QUOTA_EXCEED":
                return "超过用户单笔收款额度";
            case "DAY_RECEIVED_QUOTA_EXCEED":
                return "超过用户单日收款额度";
            case "MONTH_RECEIVED_QUOTA_EXCEED":
                return "超过用户单月收款额度";
            case "DAY_RECEIVED_COUNT_EXCEED":
                return "超过用户单日收款次数";
            case "PRODUCT_AUTH_CHECK_FAIL":
                return "未开通该权限或权限被冻结";
            case "OVERDUE_CLOSE":
                return "超过系统重试期，系统自动关闭";
            case "ID_CARD_NOT_CORRECT":
                return "收款人身份证校验不通过，请核实信息";
            case "ACCOUNT_NOT_EXIST":
                return "该用户账户不存在";
            case "TRANSFER_RISK":
                return "该笔转账可能存在风险，已被微信拦截";
            default:
                return "其它失败原因";
        }
    }

}
