package com.njzscloud.supervisory.wxPay.controller;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.google.common.base.Strings;
import com.njzscloud.common.core.ex.ExceptionMsg;
import com.njzscloud.common.core.ex.Exceptions;
import com.njzscloud.common.core.utils.R;
import com.njzscloud.common.security.ex.UserLoginException;
import com.njzscloud.common.security.util.SecurityUtil;
import com.njzscloud.common.wechat.WechatUtil;
import com.njzscloud.common.wechat.param.Code2SessionParam;
import com.njzscloud.common.wechat.result.Code2SessionResult;
import com.njzscloud.supervisory.device.service.DeviceInfoService;
import com.njzscloud.supervisory.money.contant.MoneyChangeCategory;
import com.njzscloud.supervisory.money.contant.MoneyDetailType;
import com.njzscloud.supervisory.money.contant.PayStatus;
import com.njzscloud.supervisory.money.pojo.entity.MoneyChangeDetailEntity;
import com.njzscloud.supervisory.money.service.MoneyChangeDetailService;
import com.njzscloud.supervisory.order.contant.MoneyWay;
import com.njzscloud.supervisory.order.contant.OrderStatus;
import com.njzscloud.supervisory.order.contant.PaymentStatus;
import com.njzscloud.supervisory.order.contant.SettlementWay;
import com.njzscloud.supervisory.order.pojo.entity.OrderExpenseItemsEntity;
import com.njzscloud.supervisory.order.pojo.entity.OrderGoodsEntity;
import com.njzscloud.supervisory.order.pojo.entity.OrderInfoEntity;
import com.njzscloud.supervisory.order.pojo.param.PaymentItemParam;
import com.njzscloud.supervisory.order.pojo.result.PaymentContextResult;
import com.njzscloud.supervisory.order.service.OrderExpenseItemsService;
import com.njzscloud.supervisory.order.service.OrderGoodsService;
import com.njzscloud.supervisory.order.service.OrderInfoService;
import com.njzscloud.supervisory.wxPay.config.WxPayProperties;
import com.njzscloud.supervisory.wxPay.dto.RefundRequestDto;
import com.njzscloud.supervisory.wxPay.param.PaymentParam;
import com.njzscloud.supervisory.wxPay.service.PaymentService;
import com.njzscloud.supervisory.wxPay.utils.RequestHolder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * 支付相关接口
 * 使用微信支付官方SDK的生产级实现
 *
 * @author ljw
 */
@Slf4j
@RestController
@RequestMapping("/payment")
@RequiredArgsConstructor
public class PaymentController {

    private final OrderExpenseItemsService orderExpenseItemsService;
    private final OrderInfoService orderInfoService;
    private final WxPayService wxPayService;
    private final WxPayProperties properties;
    private final OrderGoodsService orderGoodsService;
    private final PaymentService paymentService;
    private final MoneyChangeDetailService moneyChangeDetailService;

    /**
     * 发起支付（使用生产级微信支付SDK）
     */
    @PostMapping("/pay")
    @Transactional(rollbackFor = Exception.class)
    public R<?> pay(@RequestBody PaymentParam paymentParam) {
        // 入参校验：结算金额、订单ID、支付清单不能为空
        if (paymentParam == null
                || paymentParam.getOrderId() == null
                || paymentParam.getSettleTotalMoney() == null
                || paymentParam.getSettleTotalMoney().signum() < 0
                || paymentParam.getItems() == null) {
            throw Exceptions.clierr("参数不完整或支付总金额小于0");
        }

        // 校验支付清单：id、名称、金额
        boolean invalidItem = paymentParam.getItems().stream().anyMatch(it ->
                it == null || it.getId() == null || Strings.isNullOrEmpty(it.getExpenseItemName()) || it.getSettleMoney() == null
                        || it.getSettleMoney().signum() < 0
        );
        if (invalidItem) {
            throw Exceptions.clierr("支付清单项不合法（id/名称/金额）");
        }

        // 校验数据库中结算金额是否与请求一致
        for (PaymentItemParam it : paymentParam.getItems()) {
            OrderExpenseItemsEntity entity = orderExpenseItemsService.getById(it.getId());
            if (null == entity) {
                throw Exceptions.clierr("支付清单项不存在，id=" + it.getId());
            }
            BigDecimal dbSettle = entity.getSettleMoney();
            if (dbSettle == null || dbSettle.compareTo(it.getSettleMoney()) != 0) {
                throw Exceptions.clierr("支付清单项结算金额不匹配【" + it.getExpenseItemName() + "】(id=" + it.getId()
                        + ")，系统:" + dbSettle + "，请求:" + it.getSettleMoney());
            }
        }

        // 查询订单及相关支付上下文
        PaymentContextResult ctx = orderInfoService.paymentContext(paymentParam.getOrderId());
        if (ctx == null || ctx.getOrderId() == null) {
            throw Exceptions.clierr("订单不存在");
        }

        // 验证总金额是否与参数中的结算总金额一致
        if (paymentParam.getSettleTotalMoney() == null ||
                paymentParam.getSettleTotalMoney().compareTo(ctx.getSettleMoney()) != 0) {
            throw Exceptions.clierr("结算总金额与实际总金额不一致");
        }

        // 检查是否已存在资金明细记录
        MoneyChangeDetailEntity existingDetail = moneyChangeDetailService.getByOrderIdAndType(
                paymentParam.getOrderId(), MoneyDetailType.WX);
        if (existingDetail != null && PayStatus.PAID.equals(existingDetail.getStatus())) {
            throw Exceptions.clierr("该订单已支付，无需重复支付");
        }

        try {
            // 构建微信支付请求
            String outTradeNo = generateOutTradeNo(ctx.getSn());
            WxPayUnifiedOrderRequest wxRequest = new WxPayUnifiedOrderRequest();
            wxRequest.setOutTradeNo(outTradeNo);
            wxRequest.setBody("订单支付-108-" + ctx.getSn());
            // 转换为分
            wxRequest.setTotalFee(ctx.getSettleMoney().multiply(new BigDecimal("100")).intValue());
            wxRequest.setTradeType("JSAPI");
            wxRequest.setSpbillCreateIp(RequestHolder.getClientIP());
            // 需要配置实际的回调地址
            wxRequest.setNotifyUrl(properties.getNotifyUrl());
            // 设置分账标识为Y，开启分账功能
            wxRequest.setProfitSharing("Y");
            // 在服务商模式下，设置收款方子商户号
            wxRequest.setSubMchId(properties.getSubMchId());
            wxRequest.setSubOpenid(getCurrentUserOpenid(paymentParam.getWxCode()));

            // 调用微信支付服务（使用服务商WxPayService，因为需要分账权限验证）
            log.info("开始创建微信支付JSAPI订单，使用服务商WxPayService，商户号：{}，收款方商户号：{}，分账商户号：{}",
                    properties.getMchId(), properties.getSubMchId(), properties.getReceiverMchId());
            log.info("开始创建微信支付JSAPI订单，入参为：{}", JSON.toJSONString(wxRequest));
            WxPayMpOrderResult result = wxPayService.createOrder(wxRequest);
            log.info("创建微信支付JSAPI订单，返回结果为：{}", JSON.toJSONString(result));
            // 更新订单状态为待支付
            orderInfoService.lambdaUpdate()
                    .eq(OrderInfoEntity::getId, paymentParam.getOrderId())
                    .set(OrderInfoEntity::getPaymentStatus, PaymentStatus.WeiZhiFu)
                    .set(OrderInfoEntity::getSettlementWay, SettlementWay.CASH.getVal())
                    .set(OrderInfoEntity::getOutTradeNo, outTradeNo)
                    .update();

            // 创建或更新资金明细
            if (existingDetail == null) {
                // 新建资金明细
                MoneyChangeDetailEntity newDetail = new MoneyChangeDetailEntity();
                newDetail.setType(MoneyDetailType.WX);
                newDetail.setStatus(PayStatus.PENDING);
                newDetail.setOrderId(paymentParam.getOrderId());
                newDetail.setUserId(SecurityUtil.currentUserId());
                // 扣款为负数
                newDetail.setDelta(ctx.getSettleMoney().negate());
                newDetail.setMoneyChangeCategory(MoneyChangeCategory.DingDanKouKuan);
                newDetail.setMemo("微信支付订单：" + outTradeNo);
                moneyChangeDetailService.save(newDetail);
            } else {
                // 更新现有资金明细状态为待支付
                existingDetail.setStatus(PayStatus.PENDING);
                existingDetail.setUserId(SecurityUtil.currentUserId());
                existingDetail.setDelta(ctx.getSettleMoney().negate());
                existingDetail.setMemo("微信支付订单：" + outTradeNo);
                moneyChangeDetailService.updateById(existingDetail);
            }

            log.info("微信支付订单创建成功（生产级SDK），订单ID：{}，微信订单号：{}", paymentParam.getOrderId(), outTradeNo);

            return R.success(result);
        } catch (WxPayException e) {
            log.error("微信支付订单创建失败，订单ID：{}，错误信息：{}", paymentParam.getOrderId(), e.getMessage(), e);
            WxPayNotifyResponse.fail(e.getMessage());
        }

        return R.success();
    }

    /**
     * 获取当前用户openid（使用小程序APPID）
     */
    public String getCurrentUserOpenid(String wxCode) {
        // 使用小程序APPID（子商户）来获取openid，因为前端wx.login()使用的是子商户APPID
        Code2SessionParam param = new Code2SessionParam()
                .setJs_code(wxCode);

        log.info("获取openid，使用小程序APPID，code：{}", wxCode);

        Code2SessionResult sessionResult = WechatUtil.code2Session(param);
        Integer errcode = sessionResult.getErrcode();
        if (errcode != null && errcode != 0) {
            log.error("微信登录失败, errcode: {}, errmsg: {}", errcode, sessionResult.getErrmsg());
            throw new UserLoginException(ExceptionMsg.CLI_ERR_MSG, "微信登录失败");
        }

        log.info("获取openid成功：{}", sessionResult.getOpenid());
        return sessionResult.getOpenid();
    }

    /**
     * 生成符合微信要求的商户订单号（<=32字节，字母数字-_-）
     */
    private String generateOutTradeNo(String sn) {
        String safeSn = sn == null ? "" : sn.replaceAll("[^0-9A-Za-z_-]", "");
        // 8位以内
        String suffix = String.valueOf(System.currentTimeMillis() % 100000000L);
        String base = "ORDER_" + safeSn + "_" + suffix;
        if (base.length() <= 32) {
            return base;
        }
        // 超长则从左侧截断，仅保留最后32位，仍保持后缀时间以提高唯一性
        return base.substring(base.length() - 32);
    }

    /**
     * 从商户订单号中提取订单sn
     */
    private String extractOrderIdFromOutTradeNo(String outTradeNo) {
        try {
            if (outTradeNo != null && outTradeNo.startsWith("ORDER_")) {
                String[] parts = outTradeNo.split("_");
                if (parts.length >= 2) {
                    return parts[1];
                }
            }
        } catch (Exception e) {
            log.error("解析订单号失败：{}", outTradeNo, e);
        }
        return null;
    }

    /**
     * 根据订单ID获取微信交易ID
     */
    private String getTransactionIdByOrderId(Long orderId) {
        log.debug("开始获取交易ID，订单ID：{}", orderId);

        // 从资金明细的扩展信息中获取交易ID
        MoneyChangeDetailEntity detail = moneyChangeDetailService.getByOrderIdAndType(orderId, MoneyDetailType.WX);

        if (detail == null) {
            log.warn("未找到订单的资金明细记录，订单ID：{}", orderId);
            return null;
        }

        log.debug("找到资金明细记录，ID：{}，扩展信息：{}", detail.getId(), detail.getExtendInfo());

        if (detail.getExtendInfo() == null) {
            log.warn("资金明细扩展信息为空，订单ID：{}", orderId);
            return null;
        }

        // 解析JSON格式的扩展信息获取transactionId
        try {
            // 使用简单的字符串解析，实际项目中建议使用JSON库
            String extendInfo = detail.getExtendInfo();
            log.debug("解析扩展信息：{}", extendInfo);

            if (extendInfo.contains("transactionId")) {
                int startIndex = extendInfo.indexOf("\"transactionId\":\"") + 16;
                int endIndex = extendInfo.indexOf("\"", startIndex);
                if (startIndex > 15 && endIndex > startIndex) {
                    String transactionId = extendInfo.substring(startIndex, endIndex);
                    log.info("成功获取交易ID：{}，订单ID：{}", transactionId, orderId);
                    return transactionId;
                } else {
                    log.warn("交易ID格式不正确，startIndex：{}，endIndex：{}，订单ID：{}", startIndex, endIndex, orderId);
                }
            } else {
                log.warn("扩展信息中不包含transactionId，订单ID：{}", orderId);
            }
        } catch (Exception e) {
            log.error("解析交易ID异常，订单ID：{}，扩展信息：{}，错误：{}", orderId, detail.getExtendInfo(), e.getMessage(), e);
        }

        log.warn("获取交易ID失败，订单ID：{}", orderId);
        return null;
    }


    /**
     * 微信支付回调接口
     */
    @PostMapping(value = "/wechat/notify", produces = "text/xml;charset=utf-8")
    public String wechatPayNotify(@RequestBody String xmlData) {
        try {
            log.info("收到微信支付回调：{}", xmlData);
            WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData);
            String orderSn = extractOrderIdFromOutTradeNo(notifyResult.getOutTradeNo());
            if (orderSn != null) {
                OrderInfoEntity entity = orderInfoService.getOne(Wrappers.<OrderInfoEntity>lambdaQuery().eq(OrderInfoEntity::getSn, orderSn));
                log.info("微信支付成功，商户订单号：{}，微信交易号：{}",
                        orderSn, notifyResult.getTransactionId());
                if (entity == null) {
                    log.info("订单信息不存在：{}", orderSn);
                } else {
                    OrderGoodsEntity orderGoodsEntity = orderGoodsService.getById(entity.getGoodsId());
                    String moneyWay = orderGoodsEntity.getMoneyWay();
                    boolean out = MoneyWay.OUT.getVal().equals(moneyWay);
                    orderInfoService.updateById(new OrderInfoEntity()
                            .setId(entity.getId())
                            .setPaymentStatus(PaymentStatus.YiZhiFu)
                            .setOrderStatus(out ? OrderStatus.YiWanCheng : null)
                            .setPayTime(LocalDateTime.now())
                    );

                    // 更新资金明细状态为已支付
                    MoneyChangeDetailEntity payDetail = moneyChangeDetailService.getByOrderIdAndType(entity.getId(), MoneyDetailType.WX);
                    if (payDetail != null) {
                        payDetail.setStatus(PayStatus.PAID);
                        moneyChangeDetailService.updateById(payDetail);
                        log.info("支付回调：资金明细状态更新为已支付，订单ID：{}", entity.getId());
                    }

                    // 执行分账
                    log.info("支付回调：开始执行分账，订单ID：{}，支付金额：{}元，交易ID：{}",
                            entity.getId(), entity.getSettleMoney(), notifyResult.getTransactionId());
                    try {
                        paymentService.profitSharingAsync(entity.getId(), notifyResult.getTransactionId(), entity.getSettleMoney());
                        log.info("支付回调：分账成功，订单ID：{}", entity.getId());
                    } catch (Exception e) {
                        log.error("支付回调：分账失败，订单ID：{}，支付金额：{}元，交易ID：{}，错误：{}",
                                entity.getId(), entity.getSettleMoney(), notifyResult.getTransactionId(), e.getMessage(), e);
                        // 分账失败不影响支付成功，但需要记录
                    }

                    // 保存交易ID到资金明细的扩展信息中
                    if (payDetail != null) {
                        // 将交易ID保存到扩展信息中，格式：{"transactionId":"xxx"}
                        String extendInfo = String.format("{\"transactionId\":\"%s\"}", notifyResult.getTransactionId());
                        payDetail.setExtendInfo(extendInfo);
                        moneyChangeDetailService.updateById(payDetail);
                    }

                    if (out) {
                        DeviceInfoService.open(orderSn);
                    }
                }
            } else {
                log.warn("无法从商户订单号中提取订单");
            }
            String responseXml = WxPayNotifyResponse.success("OK");
            log.info("准备返回给微信的支付回调XML响应: {}", responseXml);
            return responseXml;
        } catch (WxPayException e) {
            log.error(e.getMessage());
            return WxPayNotifyResponse.fail(e.getMessage());
        }
    }

    /**
     * 统一退款接口 - 支持微信退款和公司退款
     */
    @PostMapping("/refund")
    public R<?> refund(@RequestBody RefundRequestDto refundRequest) {
        // 验证订单存在性
        OrderInfoEntity orderInfo = orderInfoService.getById(refundRequest.getOrderId());
        if (null == orderInfo) {
            throw Exceptions.clierr("订单不存在");
        }

        // 验证订单状态
        if (!PaymentStatus.YiZhiFu.getVal().equals(orderInfo.getPaymentStatus().getVal())) {
            throw Exceptions.clierr("订单未支付，无法退款");
        }
        if (refundRequest.getRefundAmount() == null) {
            throw Exceptions.clierr("公司退款金额不能为空");
        }

        if (refundRequest.getRefundAmount().compareTo(BigDecimal.ZERO) <= 0) {
            throw Exceptions.clierr("退款金额必须大于0");
        }
        // 获取支付上下文
        PaymentContextResult ctx = orderInfoService.paymentContext(refundRequest.getOrderId());
        if (null == ctx) {
            throw Exceptions.clierr("获取支付上下文失败");
        }

        if (refundRequest.getRefundAmount().compareTo(ctx.getSettleMoney()) > 0) {
            throw Exceptions.clierr("退款金额不能超过订单已结算金额");
        }

        // 如果订单再次退款，本次退款金额+已退款金额不能大于结算金额
        if (refundRequest.getRefundAmount().add(ctx.getRefundMoney()).compareTo(ctx.getSettleMoney()) > 0) {
            throw Exceptions.clierr("退款金额总和不能超过订单已结算金额");
        }
        refundRequest.setOutTradeNo(orderInfo.getOutTradeNo());

        // 如果是微信支付，需要先执行分账回退
        if (SettlementWay.CASH.getVal().equals(ctx.getOiPayWay())) {
            log.info("退款处理：开始分账回退，订单ID：{}，退款金额：{}元，支付方式：{}",
                    orderInfo.getId(), refundRequest.getRefundAmount(), ctx.getOiPayWay());
            try {
                paymentService.profitSharingReturn(orderInfo.getId(), refundRequest.getRefundAmount());
                log.info("退款前分账回退成功，订单ID：{}，退款金额：{}", orderInfo.getId(), refundRequest.getRefundAmount());
            } catch (Exception e) {
                log.error("退款前分账回退失败，订单ID：{}，退款金额：{}元，错误：{}",
                        orderInfo.getId(), refundRequest.getRefundAmount(), e.getMessage(), e);
                throw Exceptions.clierr("分账回退失败，无法退款");
            }
        }

        paymentService.refund(refundRequest, ctx, Boolean.FALSE);

        // 微信支付的退款处理
        if (SettlementWay.CASH.getVal().equals(ctx.getOiPayWay())) {
            // 计算剩余金额 = 原结算金额 - 已退款金额 - 本次退款金额
            BigDecimal remainingAmount = ctx.getSettleMoney()
                    .subtract(ctx.getRefundMoney() == null ? BigDecimal.ZERO : ctx.getRefundMoney())
                    .subtract(refundRequest.getRefundAmount());

            // 如果剩余金额大于0，说明是部分退款，需要重新分账
            if (remainingAmount.compareTo(BigDecimal.ZERO) > 0) {
                log.info("部分退款：检测到剩余金额{}元，开始重新分账，订单ID：{}", remainingAmount, orderInfo.getId());
                try {
                    // 查询原始交易ID
                    String transactionId = getTransactionIdByOrderId(orderInfo.getId());
                    if (transactionId != null) {
                        log.info("部分退款：获取到交易ID：{}，开始重新分账", transactionId);
                        paymentService.reProfitSharing(orderInfo.getId(), transactionId, remainingAmount);
                        log.info("部分退款后重新分账成功，订单ID：{}，剩余金额：{}元，交易ID：{}",
                                orderInfo.getId(), remainingAmount, transactionId);
                    } else {
                        log.warn("部分退款后无法获取交易ID，跳过重新分账，订单ID：{}", orderInfo.getId());
                        log.warn("请检查资金明细表中是否正确存储了交易ID信息");
                    }
                } catch (Exception e) {
                    log.error("部分退款后重新分账失败，订单ID：{}，剩余金额：{}元，错误：{}",
                            orderInfo.getId(), remainingAmount, e.getMessage(), e);
                    // 重新分账失败不影响退款成功，但需要记录
                }
            } else {
                log.info("部分退款：剩余金额为0，无需重新分账，订单ID：{}", orderInfo.getId());
            }

            // 更新订单状态为已退款
            orderInfoService.lambdaUpdate()
                    .eq(OrderInfoEntity::getId, refundRequest.getOrderId())
                    .set(OrderInfoEntity::getPaymentStatus, PaymentStatus.YiTuiKuan)
                    .set(OrderInfoEntity::getRefundMoney,
                            (ctx.getRefundMoney() == null ? BigDecimal.ZERO : ctx.getRefundMoney()).add(refundRequest.getRefundAmount()))
                    .set(OrderInfoEntity::getRefundTime, LocalDateTime.now())
                    .update();
        } else if (SettlementWay.MONTH.getVal().equals(ctx.getOiPayWay()) || SettlementWay.BALANCE.getVal().equals(ctx.getOiPayWay())) {
            // 月结和余额支付的退款处理
            orderInfoService.lambdaUpdate()
                    .eq(OrderInfoEntity::getId, refundRequest.getOrderId())
                    .set(OrderInfoEntity::getPaymentStatus, PaymentStatus.YiTuiKuan)
                    .set(OrderInfoEntity::getRefundMoney, refundRequest.getRefundAmount())
                    .set(OrderInfoEntity::getRefundTime, LocalDateTime.now())
                    .update();
        }

        return R.success();
    }

    /**
     * 微信退款回调
     */
    @PostMapping(value = "/wechat/refundNotify", produces = "text/xml;charset=utf-8")
    public String parseRefundNotifyResult(@RequestBody String xmlData) {
        try {
            log.info("收到微信退款回调：{}", xmlData);
            WxPayRefundNotifyResult result = wxPayService.parseRefundNotifyResult(xmlData);
            log.info("退款回调解析结果：{}", result);
            String orderSn = extractOrderIdFromOutTradeNo(result.getReqInfo().getOutTradeNo());
            log.info("从退款回调中提取订单号：{}", orderSn);
            OrderInfoEntity entity = orderInfoService.getOne(Wrappers.<OrderInfoEntity>lambdaQuery().eq(OrderInfoEntity::getSn, orderSn));
            if (entity == null) {
                log.warn("退款回调订单不存在：{}", orderSn);
                return WxPayNotifyResponse.fail("订单不存在");
            }
            // 更新订单状态为已退款
            orderInfoService.lambdaUpdate()
                    .eq(OrderInfoEntity::getId, entity.getId())
                    .set(OrderInfoEntity::getPaymentStatus, PaymentStatus.YiTuiKuan)
                    .set(OrderInfoEntity::getRefundMoney, entity.getSettleMoney())
                    .set(OrderInfoEntity::getRefundTime, LocalDateTime.now())
                    .update();

            // 更新资金明细状态为已退款
            MoneyChangeDetailEntity refundDetail = moneyChangeDetailService.lambdaQuery()
                    .eq(MoneyChangeDetailEntity::getOrderId, entity.getId())
                    .eq(MoneyChangeDetailEntity::getType, MoneyDetailType.WX)
                    .eq(MoneyChangeDetailEntity::getStatus, PayStatus.REFUNDING)
                    .one();
            if (refundDetail != null) {
                refundDetail.setStatus(PayStatus.REFUNDED);
                moneyChangeDetailService.updateById(refundDetail);
                log.info("退款回调：资金明细状态更新为已退款，订单ID：{}", entity.getId());
            }

            log.info("退款回调处理成功，订单号：{}", orderSn);
            String responseXml = WxPayNotifyResponse.success("OK");
            log.info("准备返回给微信的退款回调XML响应: {}", responseXml);
            return responseXml;
        } catch (WxPayException e) {
            log.error("退款回调处理异常：{}", e.getMessage(), e);
            return WxPayNotifyResponse.fail(e.getMessage());
        }
    }

    /**
     * 发起支付（使用生产级微信支付SDK）
     */
    @PostMapping("/payTest")
    @Transactional(rollbackFor = Exception.class)
    public void payTest() {
        // 构建微信支付请求
        WxPayUnifiedOrderRequest wxRequest = new WxPayUnifiedOrderRequest();
        wxRequest.setOutTradeNo("53456346xdfgsdfg");
        wxRequest.setBody("订单支付-108-");
        // 转换为分
        BigDecimal settleMoney = new BigDecimal("0.01");
        wxRequest.setTotalFee(settleMoney.multiply(new BigDecimal("100")).intValue());
        // wxRequest.setOpenid("oaepd1zd7umBcg0v-dnVAN4urVc0");
        wxRequest.setSubOpenid("oaepd1zd7umBcg0v-dnVAN4urVc0");
        wxRequest.setTradeType("JSAPI");
        wxRequest.setSpbillCreateIp(RequestHolder.getClientIP());
        // 需要配置实际的回调地址
        wxRequest.setNotifyUrl(properties.getNotifyUrl());
        // 设置分账标识为Y，开启分账功能
        wxRequest.setProfitSharing("Y");
        // 在服务商模式下，设置子商户号
        wxRequest.setSubMchId(properties.getSubMchId());

        // 调用微信支付服务（使用服务商WxPayService，因为需要分账权限验证）
        try {
            log.info("测试方法：开始创建微信支付JSAPI订单，使用服务商WxPayService，商户号：{}，收款方商户号：{}，分账商户号：{}",
                    properties.getMchId(), properties.getSubMchId(), properties.getReceiverMchId());
            log.info("测试方法：开始创建微信支付JSAPI订单，入参为：{}", JSON.toJSONString(wxRequest));
            WxPayMpOrderResult result = wxPayService.createOrder(wxRequest);
            log.info("测试方法：创建微信支付JSAPI订单，返回结果为：{}", JSON.toJSONString(result));
        } catch (WxPayException e) {
            log.error("测试方法：创建订单失败", e);
            throw new RuntimeException(e);
        }
    }

    /**
     * 退款测试
     */
    @PostMapping("/refundTest")
    @Transactional(rollbackFor = Exception.class)
    public void refundTest(@RequestBody RefundRequestDto refundRequest) {
        log.info("测试方法：开始微信退款，使用服务商WxPayService，商户号：{}，收款方商户号：{}，分账商户号：{}",
                properties.getMchId(), properties.getSubMchId(), properties.getReceiverMchId());
        PaymentContextResult ctx = orderInfoService.paymentContext(refundRequest.getOrderId());
        paymentService.refund(refundRequest, ctx, Boolean.FALSE);
    }

}
