package com.haha.service.payment.impl;

import com.haha.common.constant.OrderConstants;
import com.haha.common.constant.PaymentConstants;
import com.haha.common.enums.PaymentChannel;
import com.haha.common.enums.RefundStatus;
import com.haha.entity.Order;
import com.haha.service.AccountService;
import com.haha.service.OrderService;
import com.haha.service.RefundService;
import com.haha.service.payment.*;
import com.haha.service.payment.payscore.PayScoreResult;
import com.haha.service.payment.payscore.PayScoreService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 支付业务门面服务实现
 * 统一处理支付相关业务逻辑，协调订单服务和支付策略
 */
@Slf4j
@Service
public class PaymentServiceImpl implements PaymentService {
    
    @Autowired
    private PaymentChannelFactory channelFactory;
    
    @Autowired
    private OrderService orderService;

    @Autowired
    private AccountService accountService;

    @Autowired(required = false)
    private PayScoreService payScoreService;

    @Autowired
    private RefundService refundService;

    @Autowired
    private com.haha.service.OrderInventoryService orderInventoryService;
    
    @Override
    public PaymentResult createPayment(Long orderId, PaymentChannel channel, Map<String, String> extra) {
        log.info("创建支付请求: orderId={}, channel={}", orderId, channel);
        
        // 1. 参数校验
        if (orderId == null) {
            log.error("创建支付失败: 订单ID不能为空");
            return PaymentResult.builder()
                    .success(false)
                    .errorCode("INVALID_PARAM")
                    .errorMsg("订单ID不能为空")
                    .build();
        }
        if (channel == null) {
            log.error("创建支付失败: 支付渠道不能为空, orderId={}", orderId);
            return PaymentResult.builder()
                    .success(false)
                    .errorCode("INVALID_PARAM")
                    .errorMsg("支付渠道不能为空")
                    .build();
        }
        
        // 2. 查询订单
        Order order = orderService.getById(orderId);
        if (order == null) {
            log.error("创建支付失败: 订单不存在, orderId={}", orderId);
            return PaymentResult.builder()
                    .success(false)
                    .errorCode("ORDER_NOT_FOUND")
                    .errorMsg("订单不存在")
                    .build();
        }
        
        // 3. 校验订单状态（必须是待支付状态）
        if (!OrderConstants.PAY_STATUS_UNPAID.equals(order.getPayStatus())) {
            log.error("创建支付失败: 订单状态不正确, orderId={}, payStatus={}", orderId, order.getPayStatus());
            return PaymentResult.builder()
                    .success(false)
                    .errorCode("INVALID_ORDER_STATUS")
                    .errorMsg("订单状态不正确，只有待支付订单可以发起支付")
                    .build();
        }
        
        // 4. 获取支付策略
        PaymentStrategy strategy;
        try {
            strategy = channelFactory.getStrategy(channel);
        } catch (IllegalArgumentException e) {
            log.error("创建支付失败: 不支持的支付渠道, channel={}", channel);
            return PaymentResult.builder()
                    .success(false)
                    .errorCode("UNSUPPORTED_CHANNEL")
                    .errorMsg("不支持的支付渠道: " + channel.getCode())
                    .build();
        }
        
        // 5. 构建支付请求
        PaymentRequest request = PaymentRequest.builder()
                .orderId(orderId)
                .orderNo(order.getOrderNo())
                .amount(order.getTotalAmount())
                .userId(order.getUserId())
                .channel(channel)
                .description("哈哈零售-订单支付")
                .openId(extra != null ? extra.get("openId") : null)
                .buyerId(extra != null ? extra.get("buyerId") : null)
                .extraParams(extra)
                .build();
        
        log.info("调用支付策略创建支付: orderNo={}, amount={}", order.getOrderNo(), order.getTotalAmount());
        
        // 6. 调用策略创建支付
        PaymentResult result = strategy.createPayment(request);
        
        // 7. 如果成功，更新订单的支付渠道信息
        if (result.isSuccess()) {
            order.setPayChannel(channel.getCode());
            order.setPayType(channel.getDescription());
            orderService.updateById(order);
            log.info("支付创建成功: orderId={}, channel={}", orderId, channel);
        } else {
            log.warn("支付创建失败: orderId={}, errorCode={}, errorMsg={}", 
                    orderId, result.getErrorCode(), result.getErrorMsg());
        }
        
        return result;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public RefundResult refund(Long orderId, String reason) {
        return refund(orderId, reason, null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public RefundResult refund(Long orderId, String reason, BigDecimal refundAmount) {
        log.info("发起退款请求: orderId={}, reason={}, refundAmount={}", orderId, reason, refundAmount);

        // 1. 参数校验
        if (orderId == null) {
            log.error("退款失败: 订单ID不能为空");
            return RefundResult.builder()
                    .success(false)
                    .errorCode("INVALID_PARAM")
                    .errorMsg("订单ID不能为空")
                    .build();
        }

        // 2. 查询订单
        Order order = orderService.getById(orderId);
        if (order == null) {
            log.error("退款失败: 订单不存在, orderId={}", orderId);
            return RefundResult.builder()
                    .success(false)
                    .errorCode("ORDER_NOT_FOUND")
                    .errorMsg("订单不存在")
                    .build();
        }

        // 3. 校验订单状态（已支付或部分退款均可继续退款）
        if (!OrderConstants.PAY_STATUS_PAID.equals(order.getPayStatus())
                && !OrderConstants.PAY_STATUS_PARTIAL_REFUND.equals(order.getPayStatus())) {
            log.error("退款失败: 订单状态不正确, orderId={}, payStatus={}", orderId, order.getPayStatus());
            return RefundResult.builder()
                    .success(false)
                    .errorCode("INVALID_ORDER_STATUS")
                    .errorMsg("订单状态不正确，只有已支付或部分退款订单可以退款")
                    .build();
        }

        // 4. 校验订单完成时间是否超过7天
        if (order.getPayTime() != null) {
            LocalDateTime now = LocalDateTime.now();
            long daysDiff = java.time.temporal.ChronoUnit.DAYS.between(order.getPayTime(), now);

            if (daysDiff > PaymentConstants.REFUND_MAX_DAYS) {
                log.error("退款失败: 订单已完成超过7天，不允许退款, orderId={}, payTime={}", orderId, order.getPayTime());
                return RefundResult.builder()
                        .success(false)
                        .errorCode("REFUND_EXPIRED")
                        .errorMsg("订单已完成超过7天，不支持退款")
                        .build();
            }
        }

        // 确定实际退款金额
        BigDecimal actualRefundAmount = refundAmount != null ? refundAmount
                : (order.getPaidAmount() != null ? order.getPaidAmount() : order.getTotalAmount());

        // 校验累计退款金额不超过实付金额
        BigDecimal paidAmount = order.getPaidAmount() != null ? order.getPaidAmount() : order.getTotalAmount();
        BigDecimal existingRefund = order.getRefundAmount() != null ? order.getRefundAmount() : BigDecimal.ZERO;
        BigDecimal totalAfterRefund = existingRefund.add(actualRefundAmount);
        if (totalAfterRefund.compareTo(paidAmount) > 0) {
            BigDecimal remaining = paidAmount.subtract(existingRefund);
            log.error("退款失败: 累计退款金额超过实付金额, orderId={}, existingRefund={}, requestAmount={}, remaining={}",
                    orderId, existingRefund, actualRefundAmount, remaining);
            return RefundResult.builder()
                    .success(false)
                    .errorCode("REFUND_AMOUNT_EXCEEDED")
                    .errorMsg("退款金额超过可退金额，已退" + existingRefund + "元，最多可退" + remaining + "元")
                    .build();
        }

        // 5. 根据订单的 payChannel 获取支付渠道
        PaymentChannel channel = PaymentChannel.fromCode(order.getPayChannel());

        // 6. 如果 channel 为 WECHAT_PAYSCORE，走支付分退款流程
        if (channel == PaymentChannel.WECHAT_PAYSCORE) {
            if (payScoreService == null) {
                log.error("退款失败: 支付分服务未初始化");
                return RefundResult.builder()
                        .success(false)
                        .errorCode("SERVICE_UNAVAILABLE")
                        .errorMsg("支付分服务未配置")
                        .build();
            }

            PayScoreResult payScoreResult = payScoreService.refundPayScoreOrder(
                    orderId, actualRefundAmount, reason != null ? reason : "用户申请退款");

            if (payScoreResult.isSuccess()) {
                log.info("支付分退款成功: orderId={}, refundId={}", orderId, payScoreResult.getPackageStr());
                updateOrderRefundStatus(order, reason, payScoreResult.getPackageStr(), actualRefundAmount);
                return RefundResult.builder()
                        .success(true)
                        .refundId(payScoreResult.getPackageStr())
                        .build();
            } else {
                log.warn("支付分退款失败: orderId={}, errorCode={}, errorMsg={}",
                        orderId, payScoreResult.getErrorCode(), payScoreResult.getErrorMsg());
                return RefundResult.builder()
                        .success(false)
                        .errorCode(payScoreResult.getErrorCode())
                        .errorMsg(payScoreResult.getErrorMsg())
                        .build();
            }
        }

        // 7. 如果 channel 为 null 或 BALANCE，直接更新退款状态（余额退款不经过第三方）
        if (channel == null || channel == PaymentChannel.BALANCE) {
            log.info("余额退款，直接更新订单状态: orderId={}", orderId);
            updateOrderRefundStatus(order, reason, null, actualRefundAmount);
            return RefundResult.builder()
                    .success(true)
                    .refundId("BALANCE_REFUND_" + orderId)
                    .build();
        }

        // 8. 获取支付策略
        PaymentStrategy strategy;
        try {
            strategy = channelFactory.getStrategy(channel);
        } catch (IllegalArgumentException e) {
            log.error("退款失败: 不支持的支付渠道, channel={}", channel);
            return RefundResult.builder()
                    .success(false)
                    .errorCode("UNSUPPORTED_CHANNEL")
                    .errorMsg("不支持的支付渠道: " + channel.getCode())
                    .build();
        }

        // 9. 构建退款请求
        String refundNo = generateRefundNo(order.getOrderNo());
        RefundRequest refundRequest = RefundRequest.builder()
                .orderId(orderId)
                .orderNo(order.getOrderNo())
                .transactionId(order.getTransactionId())
                .refundAmount(actualRefundAmount)
                .totalAmount(order.getTotalAmount())
                .reason(reason)
                .refundNo(refundNo)
                .build();

        log.info("调用支付策略执行退款: orderNo={}, refundNo={}, amount={}",
                order.getOrderNo(), refundNo, actualRefundAmount);

        // 10. 调用策略退款
        RefundResult result = strategy.refund(refundRequest);

        // 11. 更新订单退款状态
        if (result.isSuccess()) {
            updateOrderRefundStatus(order, reason, result.getRefundId(), actualRefundAmount);
            log.info("退款成功: orderId={}, refundId={}", orderId, result.getRefundId());
        } else {
            log.warn("退款失败: orderId={}, errorCode={}, errorMsg={}",
                    orderId, result.getErrorCode(), result.getErrorMsg());
        }

        return result;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public PaymentCallbackResult handleCallback(PaymentChannel channel, Map<String, Object> params) {
        log.info("处理支付回调: channel={}", channel);
        
        // 1. 参数校验
        if (channel == null) {
            log.error("处理回调失败: 支付渠道不能为空");
            return PaymentCallbackResult.builder()
                    .success(false)
                    .errorMsg("支付渠道不能为空")
                    .build();
        }
        if (params == null || params.isEmpty()) {
            log.error("处理回调失败: 回调参数不能为空, channel={}", channel);
            return PaymentCallbackResult.builder()
                    .success(false)
                    .errorMsg("回调参数不能为空")
                    .build();
        }
        
        // 2. 获取策略
        PaymentStrategy strategy;
        try {
            strategy = channelFactory.getStrategy(channel);
        } catch (IllegalArgumentException e) {
            log.error("处理回调失败: 不支持的支付渠道, channel={}", channel);
            return PaymentCallbackResult.builder()
                    .success(false)
                    .errorMsg("不支持的支付渠道: " + channel.getCode())
                    .build();
        }
        
        // 3. 验证签名
        // 注意：对于微信支付 V3，verifyCallback 始终返回 true，
        // 因为 V3 SDK 的签名验证由 NotificationParser 在 parseCallback 中自动完成。
        // 如果签名验证失败，parseCallback 会返回 success=false。
        if (!strategy.verifyCallback(params)) {
            log.error("处理回调失败: 签名验证失败, channel={}", channel);
            return PaymentCallbackResult.builder()
                    .success(false)
                    .errorMsg("签名验证失败")
                    .build();
        }
        
        log.info("回调签名验证通过: channel={}", channel);
        
        // 4. 解析回调（对于微信 V3，此步骤内部包含 SDK 自动签名验证）
        PaymentCallbackResult result = strategy.parseCallback(params);
        
        // 5. 如果解析成功，更新订单状态
        // 对于微信 V3，如果 SDK 签名验证失败，parseCallback 返回 success=false，不会进入此分支
        if (result.isSuccess()) {
            String orderNo = result.getOrderNo();
            log.info("回调解析成功，更新订单状态: orderNo={}, transactionId={}", orderNo, result.getTransactionId());
            
            // 更新支付状态
            boolean updated = orderService.updatePayStatus(orderNo, OrderConstants.PAY_STATUS_PAID);
            if (!updated) {
                log.warn("更新订单支付状态失败: orderNo={}", orderNo);
            }
            
            // 更新 transactionId 和 payTime
            Order order = orderService.getOrderByOutTradeNo(orderNo);
            if (order == null) {
                // 尝试通过 orderNo 查找
                order = orderService.lambdaQuery()
                        .eq(Order::getOrderNo, orderNo)
                        .one();
            }
            
            if (order != null) {
                order.setTransactionId(result.getTransactionId());
                order.setPayTime(result.getPayTime() != null ? result.getPayTime() : LocalDateTime.now());
                orderService.updateById(order);
                log.info("订单更新成功: orderId={}, transactionId={}, payTime={}",
                        order.getId(), order.getTransactionId(), order.getPayTime());

                // 支付成功后扣减库存
                try {
                    orderInventoryService.decreaseStockOnPaid(order);
                } catch (Exception e) {
                    log.error("支付回调扣减库存异常: orderNo={}", orderNo, e);
                }
            } else {
                log.error("订单不存在，无法更新transactionId: orderNo={}", orderNo);
            }
        } else {
            log.warn("回调解析失败: channel={}, errorMsg={}", channel, result.getErrorMsg());
        }
        
        return result;
    }
    
    @Override
    public PaymentResult queryPaymentStatus(Long orderId) {
        log.info("查询支付状态: orderId={}", orderId);
        
        // 1. 参数校验
        if (orderId == null) {
            log.error("查询支付状态失败: 订单ID不能为空");
            return PaymentResult.builder()
                    .success(false)
                    .errorCode("INVALID_PARAM")
                    .errorMsg("订单ID不能为空")
                    .build();
        }
        
        // 2. 查询订单
        Order order = orderService.getById(orderId);
        if (order == null) {
            log.error("查询支付状态失败: 订单不存在, orderId={}", orderId);
            return PaymentResult.builder()
                    .success(false)
                    .errorCode("ORDER_NOT_FOUND")
                    .errorMsg("订单不存在")
                    .build();
        }
        
        // 3. 获取支付渠道
        PaymentChannel channel = PaymentChannel.fromCode(order.getPayChannel());
        if (channel == null) {
            log.warn("订单无支付渠道信息，返回本地状态: orderId={}, payStatus={}", orderId, order.getPayStatus());
            boolean isPaid = OrderConstants.PAY_STATUS_PAID.equals(order.getPayStatus());
            return PaymentResult.builder()
                    .success(isPaid)
                    .errorCode(isPaid ? null : OrderConstants.PAY_STATUS_UNPAID)
                    .errorMsg(isPaid ? null : "订单未支付")
                    .build();
        }

        // 4. 如果是余额支付，直接返回本地状态
        if (channel == PaymentChannel.BALANCE) {
            boolean isPaid = OrderConstants.PAY_STATUS_PAID.equals(order.getPayStatus());
            log.info("余额支付，返回本地状态: orderId={}, isPaid={}", orderId, isPaid);
            return PaymentResult.builder()
                    .success(isPaid)
                    .channel(channel)
                    .errorCode(isPaid ? null : OrderConstants.PAY_STATUS_UNPAID)
                    .errorMsg(isPaid ? null : "订单未支付")
                    .build();
        }
        
        // 5. 调用策略查询
        PaymentStrategy strategy;
        try {
            strategy = channelFactory.getStrategy(channel);
        } catch (IllegalArgumentException e) {
            log.error("查询支付状态失败: 不支持的支付渠道, channel={}", channel);
            return PaymentResult.builder()
                    .success(false)
                    .errorCode("UNSUPPORTED_CHANNEL")
                    .errorMsg("不支持的支付渠道: " + channel.getCode())
                    .build();
        }
        
        log.info("调用支付策略查询状态: orderNo={}, channel={}", order.getOrderNo(), channel);
        PaymentResult result = strategy.queryPayment(order.getOrderNo());
        result.setChannel(channel);
        
        return result;
    }
    
    @Override
    public List<PaymentChannel> getAvailableChannels() {
        log.debug("获取可用支付渠道列表");
        return channelFactory.getAvailableChannels();
    }

    @Override
    public PaymentResult createPayment(Map<String, Object> params) {
        // 1. 提取和校验参数
        Object orderIdObj = params.get("orderId");
        Object channelObj = params.get("channel");

        if (orderIdObj == null || orderIdObj.toString().isEmpty()) {
            return PaymentResult.builder()
                    .success(false)
                    .errorCode("INVALID_PARAM")
                    .errorMsg("参数错误：orderId 不能为空")
                    .build();
        }
        if (channelObj == null || channelObj.toString().isEmpty()) {
            return PaymentResult.builder()
                    .success(false)
                    .errorCode("INVALID_PARAM")
                    .errorMsg("参数错误：channel 不能为空")
                    .build();
        }

        Long orderId;
        try {
            orderId = Long.valueOf(orderIdObj.toString());
        } catch (NumberFormatException e) {
            log.error("orderId 格式错误: {}", orderIdObj);
            return PaymentResult.builder()
                    .success(false)
                    .errorCode("INVALID_PARAM")
                    .errorMsg("参数错误：orderId 格式不正确")
                    .build();
        }

        String channelCode = channelObj.toString();

        // 2. 转换 channel 字符串为 PaymentChannel 枚举
        PaymentChannel channel = PaymentChannel.fromCode(channelCode);
        if (channel == null) {
            log.warn("不支持的支付渠道: {}", channelCode);
            return PaymentResult.builder()
                    .success(false)
                    .errorCode("UNSUPPORTED_CHANNEL")
                    .errorMsg("不支持的支付渠道: " + channelCode)
                    .build();
        }

        // 3. 构建 extra Map
        Map<String, String> extra = new HashMap<>();
        if (params.containsKey("openId")) {
            extra.put("openId", params.get("openId").toString());
        }
        if (params.containsKey("buyerId")) {
            extra.put("buyerId", params.get("buyerId").toString());
        }

        log.info("创建支付请求 - 订单ID: {}, 渠道: {}", orderId, channel.getDescription());
        return createPayment(orderId, channel, extra);
    }

    @Override
    public RefundResult refund(Map<String, Object> params) {
        if (!params.containsKey("orderId")) {
            return RefundResult.builder()
                    .success(false)
                    .errorCode("INVALID_PARAM")
                    .errorMsg("参数错误：orderId 不能为空")
                    .build();
        }

        Long orderId = Long.valueOf(params.get("orderId").toString());
        String reason = params.containsKey("reason") ? params.get("reason").toString() : "用户申请退款";

        // 提取商品列表和自定义金额
        @SuppressWarnings("unchecked")
        List<Map<String, Object>> products = (List<Map<String, Object>>) params.get("products");
        BigDecimal customRefundAmount = null;
        if (params.containsKey("refundAmount") && params.get("refundAmount") != null) {
            customRefundAmount = new BigDecimal(params.get("refundAmount").toString());
        }

        // 是否立即执行退款（管理员直接退款 vs 用户提交申请）
        boolean immediate = params.containsKey("immediate") && Boolean.TRUE.equals(params.get("immediate"));

        // 退款后是否恢复库存（默认恢复）
        Boolean restoreStock = null;
        if (params.containsKey("restoreStock") && params.get("restoreStock") != null) {
            Object val = params.get("restoreStock");
            restoreStock = val instanceof Boolean ? (Boolean) val : Boolean.parseBoolean(val.toString());
        }

        try {
            // 创建退款记录（PENDING）
            com.haha.entity.Refund refundRecord = refundService.createRefundRecord(orderId, reason, products, customRefundAmount, restoreStock);
            BigDecimal refundAmount = refundRecord.getRefundAmount();

            if (immediate) {
                // 管理员直接退款：立即执行第三方退款
                RefundResult result = refund(orderId, reason, refundAmount);
                if (result.isSuccess()) {
                    refundService.markRefunded(refundRecord.getId(), result.getRefundId());
                    Order order = orderService.getById(orderId);
                    if (order != null) {
                        order.setCurrentRefundId(refundRecord.getId());
                        orderService.updateById(order);
                    }
                    log.info("管理员直接退款成功 - orderId: {}, refundId: {}, amount: {}",
                            orderId, refundRecord.getId(), refundAmount);
                }
                return result;
            } else {
                // 用户端提交：仅创建申请，等待管理员审核
                log.info("退款申请已创建，等待审核 - orderId: {}, refundId: {}, amount: {}, items: {}",
                        orderId, refundRecord.getId(), refundRecord.getRefundAmount(),
                        products != null ? products.size() : 0);
                return RefundResult.builder()
                        .success(true)
                        .refundId(String.valueOf(refundRecord.getId()))
                        .build();
            }
        } catch (Exception e) {
            log.error("退款申请失败 - orderId: {}, error: {}", orderId, e.getMessage());
            return RefundResult.builder()
                    .success(false)
                    .errorCode("REFUND_ERROR")
                    .errorMsg(e.getMessage())
                    .build();
        }
    }

    @Override
    public List<Map<String, String>> getChannelList() {
        List<PaymentChannel> channels = getAvailableChannels();
        return channels.stream()
                .map(channel -> {
                    Map<String, String> map = new HashMap<>();
                    map.put("code", channel.getCode());
                    map.put("name", channel.getDescription());
                    return map;
                })
                .collect(Collectors.toList());
    }

    /**
     * 更新订单退款状态
     *
     * @param order 订单
     * @param reason 退款原因
     * @param refundId 第三方退款ID
     * @param refundAmount 退款金额（null则使用实付金额）
     */
    private void updateOrderRefundStatus(Order order, String reason, String refundId, BigDecimal refundAmount) {
        BigDecimal amount = refundAmount != null ? refundAmount
                : (order.getPaidAmount() != null ? order.getPaidAmount() : order.getTotalAmount());

        // 如果是余额支付，将退款金额退还到用户账户
        if (PaymentChannel.BALANCE.getCode().equals(order.getPayChannel())) {
            boolean balanceUpdated = accountService.updateBalance(order.getUserId(), amount);
            if (balanceUpdated) {
                log.info("余额退款 - 用户 {} 余额已增加: {}元, orderId={}",
                        order.getUserId(), amount, order.getId());
            } else {
                log.error("余额退款失败 - 用户 {} 余额退还失败: {}元, orderId={}",
                        order.getUserId(), amount, order.getId());
            }
        }

        // 累计退款金额
        BigDecimal existingRefund = order.getRefundAmount() != null ? order.getRefundAmount() : BigDecimal.ZERO;
        BigDecimal cumulativeAmount = existingRefund.add(amount);

        order.setRefundAmount(cumulativeAmount);
        order.setRefundTime(LocalDateTime.now());
        order.setRefundReason(reason);

        // 仅当累计退款 >= 实付金额时，才标记为全额退款
        BigDecimal paidAmount = order.getPaidAmount() != null ? order.getPaidAmount() : order.getTotalAmount();
        if (cumulativeAmount.compareTo(paidAmount) >= 0) {
            order.setRefundStatus(RefundStatus.REFUNDED.getCode());
            order.setPayStatus(OrderConstants.PAY_STATUS_REFUND);
            log.info("订单全额退款完成 - orderId={}, cumulativeAmount={}, paidAmount={}",
                    order.getId(), cumulativeAmount, paidAmount);
        } else {
            // 部分退款：不设 REFUNDED 状态，保留退款入口
            order.setPayStatus(OrderConstants.PAY_STATUS_PARTIAL_REFUND);
            log.info("订单部分退款 - orderId={}, cumulativeAmount={}, paidAmount={}",
                    order.getId(), cumulativeAmount, paidAmount);
        }

        orderService.updateById(order);
        // 同步退款状态到哈哈平台
        orderService.notifyHahaOrderStatusChanged(order.getOrderNo());
        log.info("订单退款状态已更新 - orderId={}, refundAmount={}(累计), payStatus={}",
                order.getId(), cumulativeAmount, order.getPayStatus());
    }
    
    /**
     * 生成退款单号
     */
    private String generateRefundNo(String orderNo) {
        return PaymentConstants.REFUND_ORDER_PREFIX + orderNo + System.currentTimeMillis();
    }
}
