package com.ruoyi.common.pay.syb.service;

import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.pay.PayApi;
import com.ruoyi.common.pay.syb.config.SybConfig;
import com.ruoyi.common.pay.syb.enums.SybTrxStatus;
import com.ruoyi.common.pay.syb.util.SybUtil;
import com.ruoyi.common.pay.Payable;
import com.ruoyi.common.pay.Refundable;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServiceUtil;
import com.ruoyi.common.utils.StringUtils;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Map;
import java.util.TreeMap;

/**
 * @author wjh
 * 2024/9/9
 */
@Service
public class SybPayService implements PayApi {

    @Autowired
    private SybPayClient sybPayClient;

    @Autowired
    private SybConfig sybConfig;

    /**
     * 微信小程序预下单
     */
    public PrepayWithRequestPaymentResponse pay(Payable payable) {
        try {
            Map<String, String> result = sybPayClient.pay(
                    payable.payableFen().longValue(),
                    payable.payableOutTradeNo(),
                    "W06",
                    payable.payableDescription(),
                    payable.payableDescription(),
                    payable.payableOpenId(),
                    "",
                    sybConfig.getNotifyUrl(),
                    "",
                    "",
                    "",
                    "",
                    sybConfig.getSubAppId(),
                    "",
                    "",
                    "",
                    "",
                    "",
                    "",
                    ""
            );

            if (result != null) {
                if (SybTrxStatus.isSuccess(result)) {
                    String payInfo = result.get("payinfo");
                    if (StringUtils.hasText(payInfo)) {
                        return JSON.parseObject(payInfo, PrepayWithRequestPaymentResponse.class);
                    }
                } else {
                    throw new ServiceException(result.get("errmsg"));
                }
            }
            throw new ServiceException("支付数据为空");
        } catch(Exception e) {
            throw new ServiceException("调起支付失败：" + e.getMessage());
        }
    }

    public boolean validSign(TreeMap<String, String> params) {
        try {
            String appkey = "";
            if("RSA".equals(params.get("signtype"))) {
                appkey = sybConfig.getRsaTlPubKey();
            } else if("SM2".equals(params.get("signtype"))) {
                appkey = sybConfig.getSm2TlPubKey();
            } else {
                appkey = sybConfig.getMd5AppKey();
            }
            boolean isSign = SybUtil.validSign(params, appkey, params.get("signtype"));// 接受到推送通知,首先验签
            System.out.println("验签结果:"+isSign);
            return isSign;
        } catch (Exception e) {
            throw new ServiceException("验签异常：" + e.getMessage());
        }
    }

    /**
     * 使用商户自定义订单编号查询支付订单
     */
    public Map<String, String> queryByOutTradeNo(String outTradeNo) {
        try {
            return sybPayClient.query(outTradeNo, "");
        } catch (Exception e) {
            throw new ServiceException("查询支付订单异常：" + e.getMessage());
        }
    }

    /**
     * 微信退款
     */
    public Map<String, String> refund(Refundable refundAble) {
        try {
            Map<String, String> result = sybPayClient.refund(
                    refundAble.refundAmount().getRefund(),
                    refundAble.refundOutRefundNo(),
                    "",
                    refundAble.refundOutTradeNo()
            );
            ServiceUtil.assertion(result == null, "退款失败，响应数据为空");
            String trxStatus = result.get("trxstatus");
            ServiceUtil.assertion(!SybTrxStatus.isSuccess(trxStatus), "发起退款失败：" + result.get("errmsg"));
            return result;
        } catch (Exception e) {
            throw new ServiceException("发起退款异常：" + e.getMessage());
        }
    }

    @Override
    public boolean isPaySuccessByOutTradeNo(String outTradeNo) {
        return isPaySuccess(this.queryByOutTradeNo(outTradeNo));
    }

    @Override
    public boolean isPaySuccess(Object result) {
        return SybTrxStatus.isSuccess((Map<String, String>)result);
    }

    @Override
    public LocalDateTime getPayTime(Object result) {
        Map<String, String> res = (Map<String, String>)result;
        return DateUtils.toLocalDateTime(res.get("fintime"), "yyyyMMddHHmmss");
    }

    /**
     * 关闭微信支付订单
     */
    public void closeByOutTradeNo(String outTradeNo) {
        try {
            sybPayClient.close("", outTradeNo);
        } catch (Exception e) {
            throw new ServiceException("关闭支付订单异常：" + e.getMessage());
        }
    }
}
