package com.ylx.common.weixinPay.service;

import cn.hutool.core.util.StrUtil;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result;
import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.ylx.common.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class WxPayV3Service {

    @Resource
    private WxPayService wxPayService;

    /**
     * V3 JSAPI下单 公众号/小程序
     */
    public Map<String, Object> createV3JsapiOrder(String orderNo, BigDecimal amount, String body, String openId, String attach) {
        try {
            // 1. 获取支付配置
            WxPayConfig payConfig = wxPayService.getConfig();

            // 2. 组装支付请求
            WxPayUnifiedOrderV3Request request = new WxPayUnifiedOrderV3Request();
            request.setOutTradeNo(orderNo);
            request.setDescription(body);
            request.setNotifyUrl(payConfig.getNotifyUrl());

            // 设置 attach 字段
            if (StrUtil.isNotBlank(attach)) {
                request.setAttach(attach);
            }

            // 金额转换（元转分，精度校验）
            int total = amount.multiply(new BigDecimal(100))
                    .setScale(0, RoundingMode.HALF_UP).intValue();
            WxPayUnifiedOrderV3Request.Amount amountObj = new WxPayUnifiedOrderV3Request.Amount();
            amountObj.setTotal(total);
            request.setAmount(amountObj);

            // 付款人信息
            WxPayUnifiedOrderV3Request.Payer payer = new WxPayUnifiedOrderV3Request.Payer();
            payer.setOpenid(openId);
            request.setPayer(payer);

            // 3. 发起支付
            WxPayUnifiedOrderV3Result result = wxPayService.unifiedOrderV3(TradeTypeEnum.JSAPI, request);
            log.info("微信支付预支付成功，prepayId: {}", result.getPrepayId());

            // 4. 生成前端JSAPI支付参数
            WxPayUnifiedOrderV3Result.JsapiResult jsapi = result.getPayInfo(
                    TradeTypeEnum.JSAPI,
                    payConfig.getAppId(),
                    payConfig.getMchId(),
                    payConfig.getPrivateKey()
            );

            // 5. 封装返回结果
            Map<String, Object> payMap = new HashMap<>();
            payMap.put("appId", jsapi.getAppId());
            payMap.put("timeStamp", jsapi.getTimeStamp());
            payMap.put("nonceStr", jsapi.getNonceStr());
            payMap.put("package", jsapi.getPackageValue());
            payMap.put("signType", jsapi.getSignType());
            payMap.put("paySign", jsapi.getPaySign());
            return payMap;

        } catch (WxPayException e) {
            // 微信支付业务异常（如签名错误、余额不足）
            log.error("微信支付业务异常，订单号: {}", orderNo, e);
            throw new ServiceException("支付失败：" + e.getMessage());
        } catch (Exception e) {
            // 系统级异常（如网络超时、配置错误）
            log.error("微信支付系统异常，订单号: {}", orderNo, e);
            throw new ServiceException("支付服务异常，请稍后重试");
        }
    }
}