package com.ycwl.basic.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ycwl.basic.dto.MobileOrderRequest;
import com.ycwl.basic.exception.BaseException;
import com.ycwl.basic.mapper.MemberMapper;
import com.ycwl.basic.model.pc.face.entity.FaceEntity;
import com.ycwl.basic.model.pc.member.resp.MemberRespVO;
import com.ycwl.basic.order.dto.*;
import com.ycwl.basic.order.entity.OrderDiscountV2;
import com.ycwl.basic.order.entity.OrderItemV2;
import com.ycwl.basic.order.entity.OrderRefundV2;
import com.ycwl.basic.order.entity.OrderV2;
import com.ycwl.basic.order.enums.*;
import com.ycwl.basic.order.exception.DuplicatePurchaseException;
import com.ycwl.basic.order.mapper.OrderDiscountMapper;
import com.ycwl.basic.order.mapper.OrderItemMapper;
import com.ycwl.basic.order.mapper.OrderV2Mapper;
import com.ycwl.basic.order.mapper.OrderRefundMapper;
import com.ycwl.basic.order.service.IOrderService;
import com.ycwl.basic.order.event.*;
import com.ycwl.basic.order.strategy.DuplicateCheckContext;
import com.ycwl.basic.order.strategy.IDuplicatePurchaseChecker;
import com.ycwl.basic.order.factory.DuplicatePurchaseCheckerFactory;
import com.ycwl.basic.product.capability.DuplicateCheckStrategy;
import com.ycwl.basic.product.capability.PricingMode;
import com.ycwl.basic.product.capability.ProductTypeCapability;
import com.ycwl.basic.product.service.IProductTypeCapabilityService;
import com.ycwl.basic.pricing.dto.DiscountDetail;
import com.ycwl.basic.pricing.dto.PriceCalculationResult;
import com.ycwl.basic.pricing.dto.ProductItem;
import com.ycwl.basic.pricing.dto.VoucherInfo;
import com.ycwl.basic.pricing.dto.CouponUseRequest;
import com.ycwl.basic.pricing.entity.PriceProductConfig;
import com.ycwl.basic.pricing.entity.PriceTierConfig;
import com.ycwl.basic.pricing.exception.PriceCalculationException;
import com.ycwl.basic.pricing.service.ICouponService;
import com.ycwl.basic.pricing.service.IProductConfigService;
import com.ycwl.basic.pricing.service.IVoucherService;
import com.ycwl.basic.pay.adapter.IPayAdapter;
import com.ycwl.basic.pay.entity.CreateOrderRequest;
import com.ycwl.basic.pay.entity.CreateOrderResponse;
import com.ycwl.basic.pay.entity.PayResponse;
import com.ycwl.basic.repository.FaceRepository;
import com.ycwl.basic.service.pc.ScenicService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import jakarta.servlet.http.HttpServletRequest;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 订单服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class OrderServiceImpl implements IOrderService {
    
    private final OrderV2Mapper orderV2Mapper;
    private final OrderItemMapper orderItemMapper;
    private final OrderDiscountMapper orderDiscountMapper;
    private final OrderRefundMapper orderRefundMapper;
    @Lazy
    private final OrderEventManager orderEventManager;
    @Lazy
    private final ScenicService scenicService;
    private final MemberMapper memberMapper;
    @Lazy
    private final ICouponService couponService;
    @Lazy
    private final IVoucherService voucherService;
    @Lazy
    private final IProductConfigService productConfigService;
    @Lazy
    private final IProductTypeCapabilityService productTypeCapabilityService;
    @Lazy
    private final DuplicatePurchaseCheckerFactory duplicatePurchaseCheckerFactory;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createOrder(MobileOrderRequest request, Long userId, Long scenicId, PriceCalculationResult priceResult) {
        Date now = new Date();
        MemberRespVO member = memberMapper.getById(userId);
        
        // 1. 检查重复购买
        log.info("开始检查重复购买: userId={}, faceId={}, scenicId={}, productCount={}", 
                userId, request.getFaceId(), scenicId, request.getProducts().size());
        checkDuplicatePurchase(userId, request.getFaceId(), scenicId, request.getProducts());
        log.info("重复购买检查通过: userId={}, faceId={}, scenicId={}", 
                userId, request.getFaceId(), scenicId);
        
        // 2. 生成订单号
        String orderNo = generateOrderNo();
        
        // 3. 创建订单基础信息
        OrderV2 order = new OrderV2();
        order.setOrderNo(orderNo);
        order.setMemberId(userId);
        order.setOpenId(member.getOpenId()); // 临时使用faceId，实际应传入openId
        order.setFaceId(request.getFaceId());
        order.setScenicId(scenicId);
        
        order.setOriginalAmount(priceResult.getOriginalAmount());
        order.setDiscountAmount(priceResult.getDiscountAmount());
        order.setFinalAmount(priceResult.getFinalAmount());
        
        order.setOrderStatus(OrderStatus.PENDING_PAYMENT);
        order.setPaymentStatus(PaymentStatus.UNPAID);
        order.setRefundStatus(RefundStatus.NO_REFUND);
        order.setTotalRefundAmount(BigDecimal.ZERO);
        
        order.setRemarks(request.getRemarks());
        order.setCreateTime(now);
        order.setUpdateTime(now);
        order.setCreateBy(userId);
        order.setUpdateBy(userId);
        order.setDeleted(0);
        
        // 保存订单
        orderV2Mapper.insert(order);
        Long orderId = order.getId();
        
        log.info("订单基础信息创建成功: orderId={}, orderNo={}", orderId, orderNo);
        
        // 4. 保存订单商品明细
        for (ProductItem product : request.getProducts()) {
            // 重新计算商品价格信息并获取商品名称
            ProductPriceAndNameInfo priceInfo = calculateProductItemPriceAndName(product);
            
            OrderItemV2 orderItem = new OrderItemV2();
            orderItem.setOrderId(orderId);
            orderItem.setProductType(product.getProductType().name());
            orderItem.setProductId(product.getProductId());
            orderItem.setProductName(priceInfo.getProductName()); // 使用配置中的商品名称
            orderItem.setQuantity(product.getQuantity() != null ? product.getQuantity() : 1);
            orderItem.setUnitPrice(product.getUnitPrice());
            orderItem.setOriginalAmount(product.getOriginalPrice());
            orderItem.setFinalAmount(product.getSubtotal());
            orderItem.setCreateTime(now);
            orderItem.setUpdateTime(now);
            
            orderItemMapper.insert(orderItem);
        }
        
        log.info("订单商品明细保存成功: orderId={}, itemCount={}", orderId, request.getProducts().size());
        
        // 5. 记录使用的优惠券信息并标记为已使用
        if (priceResult.getUsedCoupon() != null) {
            OrderDiscountV2 couponDiscount = new OrderDiscountV2();
            couponDiscount.setOrderId(orderId);
            couponDiscount.setDiscountType(DiscountType.COUPON);
            couponDiscount.setDiscountName(priceResult.getUsedCoupon().getCouponName());
            couponDiscount.setDiscountAmount(priceResult.getUsedCoupon().getActualDiscountAmount());
            couponDiscount.setSortOrder(3); // 优惠券显示顺序
            couponDiscount.setCouponId(priceResult.getUsedCoupon().getCouponId());
            couponDiscount.setCreateTime(now);
            
            orderDiscountMapper.insert(couponDiscount);
            log.info("优惠券记录保存成功: orderId={}, couponId={}, discountAmount={}", 
                    orderId, priceResult.getUsedCoupon().getCouponId(), priceResult.getUsedCoupon().getActualDiscountAmount());
            
            // 标记优惠券为已使用
            try {
                CouponUseRequest couponUseRequest = new CouponUseRequest();
                couponUseRequest.setCouponId(priceResult.getUsedCoupon().getCouponId());
                couponUseRequest.setUserId(userId);
                couponUseRequest.setOrderId(orderNo);
                couponUseRequest.setOriginalAmount(priceResult.getOriginalAmount());
                couponUseRequest.setDiscountAmount(priceResult.getUsedCoupon().getActualDiscountAmount());
                couponUseRequest.setScenicId(scenicId.toString());
                
                couponService.useCoupon(couponUseRequest);
                log.info("优惠券状态更新成功: couponId={}, orderId={}", 
                        priceResult.getUsedCoupon().getCouponId(), orderNo);
            } catch (Exception e) {
                log.error("优惠券状态更新失败: couponId={}, orderId={}, error={}", 
                        priceResult.getUsedCoupon().getCouponId(), orderNo, e.getMessage(), e);
                // 这里可以选择抛出异常或者记录错误继续执行，根据业务需求决定
                throw new BaseException("优惠券使用失败: " + e.getMessage());
            }
        }
        
        // 6. 记录使用的券码信息并标记为已使用
        if (priceResult.getUsedVoucher() != null) {
            VoucherInfo voucherInfo = priceResult.getUsedVoucher();
            OrderDiscountV2 voucherDiscount = new OrderDiscountV2();
            voucherDiscount.setOrderId(orderId);
            voucherDiscount.setDiscountType(DiscountType.VOUCHER);
            voucherDiscount.setDiscountName(voucherInfo.getBatchName());
            voucherDiscount.setDiscountAmount(voucherInfo.getActualDiscountAmount());
            voucherDiscount.setSortOrder(2); // 券码显示顺序低于限时立减
            voucherDiscount.setVoucherCode(voucherInfo.getVoucherCode());
            voucherDiscount.setCreateTime(now);
            
            orderDiscountMapper.insert(voucherDiscount);
            log.info("券码记录保存成功: orderId={}, voucherCode={}, discountAmount={}", 
                    orderId, voucherInfo.getVoucherCode(), voucherInfo.getActualDiscountAmount());
            
            // 标记券码为已使用
            try {
                String remark = "订单使用，订单号：" + orderNo;
                voucherService.markVoucherAsUsed(voucherInfo.getVoucherCode(), remark, String.valueOf(orderId), order.getDiscountAmount(), order.getFaceId());
                log.info("券码状态更新成功: voucherCode={}, orderId={}", 
                        voucherInfo.getVoucherCode(), orderNo);
            } catch (Exception e) {
                log.error("券码状态更新失败: voucherCode={}, orderId={}, error={}", 
                        voucherInfo.getVoucherCode(), orderNo, e.getMessage(), e);
                // 这里可以选择抛出异常或者记录错误继续执行，根据业务需求决定
                throw new BaseException("券码使用失败: " + e.getMessage());
            }
        }
        
        // 7. 记录其他优惠信息（如限时立减等）
        if (priceResult.getDiscountDetails() != null) {
            for (DiscountDetail discount : priceResult.getDiscountDetails()) {
                // 跳过已经记录的优惠券和券码
                if ("VOUCHER".equals(discount.getDiscountType()) || "COUPON".equals(discount.getDiscountType())) {
                    continue;
                }
                
                OrderDiscountV2 otherDiscount = new OrderDiscountV2();
                otherDiscount.setOrderId(orderId);
                otherDiscount.setDiscountType(DiscountType.fromCode(discount.getDiscountType()));
                otherDiscount.setDiscountName(discount.getDiscountName());
                otherDiscount.setDiscountAmount(discount.getDiscountAmount());
                otherDiscount.setSortOrder(discount.getSortOrder());
                otherDiscount.setCreateTime(now);
                
                orderDiscountMapper.insert(otherDiscount);
                log.info("其他优惠记录保存成功: orderId={}, type={}, discountAmount={}", 
                        orderId, discount.getDiscountType(), discount.getDiscountAmount());
            }
        }
        
        log.info("订单创建完成: orderId={}, orderNo={}, finalAmount={}", 
                orderId, orderNo, priceResult.getFinalAmount());
        
        return orderId;
    }
    
    @Override
    public OrderV2 getByOrderNo(String orderNo) {
        QueryWrapper<OrderV2> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_no", orderNo);
        queryWrapper.eq("deleted", 0);
        return orderV2Mapper.selectOne(queryWrapper);
    }
    
    @Override
    public OrderV2 getById(Long orderId) {
        return orderV2Mapper.selectById(orderId);
    }
    
    @Override
    public boolean updateOrderStatus(Long orderId, String orderStatus, String paymentStatus) {
        OrderV2 currentOrder = orderV2Mapper.selectById(orderId);
        if (currentOrder == null) {
            log.warn("订单不存在: orderId={}", orderId);
            return false;
        }

        OrderStatus targetOrderStatus = OrderStatus.fromCode(orderStatus);
        PaymentStatus targetPaymentStatus = PaymentStatus.fromCode(paymentStatus);
        validateOrderStatusTransition(currentOrder, targetOrderStatus, targetPaymentStatus);

        if (currentOrder.getOrderStatus() == targetOrderStatus
                && currentOrder.getPaymentStatus() == targetPaymentStatus) {
            return true;
        }

        OrderV2 order = new OrderV2();
        order.setId(orderId);
        order.setOrderStatus(targetOrderStatus);
        order.setPaymentStatus(targetPaymentStatus);
        order.setUpdateTime(new Date());

        if (targetPaymentStatus == PaymentStatus.PAID && currentOrder.getPayTime() == null) {
            order.setPayTime(new Date());
        }

        return orderV2Mapper.updateById(order) > 0;
    }
    
    @Override
    public String generateOrderNo() {
        // 生成订单号：ORDER + 时间戳 + 3位随机数
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String timestamp = sdf.format(new Date());
        int random = (int) (Math.random() * 900) + 100;
        return "ORDER" + timestamp + random;
    }
    
    // ====== 新增方法实现 ======
    
    @Override
    public PageInfo<OrderV2ListResponse> pageOrders(OrderV2PageRequest request) {
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        
        QueryWrapper<OrderV2> queryWrapper = buildOrderQueryWrapper(request);
        List<OrderV2> orders = orderV2Mapper.selectList(queryWrapper);
        
        // 转换为响应DTO
        List<OrderV2ListResponse> responseList = orders.stream()
                .map(this::convertToListResponse)
                .collect(Collectors.toList());
        
        return new PageInfo<>(responseList);
    }
    
    @Override
    public OrderV2DetailResponse getOrderDetail(Long orderId) {
        // 查询订单基础信息
        OrderV2 order = orderV2Mapper.selectById(orderId);
        if (order == null || order.getDeleted() == 1) {
            return null;
        }
        
        // 查询订单商品明细
        QueryWrapper<OrderItemV2> itemQuery = new QueryWrapper<>();
        itemQuery.eq("order_id", orderId);
        List<OrderItemV2> orderItems = orderItemMapper.selectList(itemQuery);
        
        // 查询订单优惠记录
        QueryWrapper<OrderDiscountV2> discountQuery = new QueryWrapper<>();
        discountQuery.eq("order_id", orderId).orderByAsc("sort_order");
        List<OrderDiscountV2> orderDiscounts = orderDiscountMapper.selectList(discountQuery);
        
        // 查询订单退款记录
        QueryWrapper<OrderRefundV2> refundQuery = new QueryWrapper<>();
        refundQuery.eq("order_id", orderId).orderByDesc("create_time");
        List<OrderRefundV2> orderRefunds = orderRefundMapper.selectList(refundQuery);
        
        // 转换为响应DTO
        return convertToDetailResponse(order, orderItems, orderDiscounts, orderRefunds);
    }
    
    @Override
    @Transactional
    public boolean updateOrderRemarks(Long orderId, String remarks) {
        OrderV2 order = new OrderV2();
        order.setId(orderId);
        order.setRemarks(remarks);
        order.setUpdateTime(new Date());
        
        return orderV2Mapper.updateById(order) > 0;
    }
    
    @Override
    @Transactional
    public boolean updatePaymentStatus(Long orderId, String paymentStatus) {
        // 先查询当前订单状态
        OrderV2 currentOrder = orderV2Mapper.selectById(orderId);
        if (currentOrder == null) {
            log.warn("订单不存在: orderId={}", orderId);
            return false;
        }

        PaymentStatus targetPaymentStatus = PaymentStatus.fromCode(paymentStatus);
        validatePaymentStatusTransition(currentOrder, targetPaymentStatus);

        PaymentStatus oldPaymentStatus = currentOrder.getPaymentStatus();
        if (oldPaymentStatus == targetPaymentStatus) {
            return true;
        }

        OrderV2 order = new OrderV2();
        order.setId(orderId);
        order.setPaymentStatus(targetPaymentStatus);
        order.setOrderStatus(OrderStatus.PAID);
        order.setUpdateTime(new Date());

        if (currentOrder.getPayTime() == null) {
            order.setPayTime(new Date());
        }

        boolean success = orderV2Mapper.updateById(order) > 0;

        if (success) {
            PaymentStatusChangeEvent event = new PaymentStatusChangeEvent(
                    orderId, currentOrder.getOrderNo(),
                    oldPaymentStatus, targetPaymentStatus,
                    "支付状态更新", null
            );
            orderEventManager.publishPaymentStatusChangeEvent(event);
        }

        return success;
    }
    
    @Override
    @Transactional
    public boolean updateRefundStatus(Long orderId, RefundStatus refundStatus, String refundNo, String paymentRefundId) {
        OrderV2 currentOrder = orderV2Mapper.selectById(orderId);
        if (currentOrder == null) {
            log.warn("订单不存在: orderId={}", orderId);
            return false;
        }

        if (refundStatus == null) {
            throw new BaseException("退款状态不能为空");
        }

        validateRefundStatusTransition(currentOrder, refundStatus);

        OrderRefundV2 refundRecord = resolveRefundRecord(orderId, refundNo);
        String resolvedRefundNo = refundRecord.getRefundNo();
        if (StringUtils.isBlank(resolvedRefundNo)) {
            throw new BaseException("退款单号不能为空");
        }

        RefundStatus oldRefundStatus = currentOrder.getRefundStatus();
        boolean refundStatusChanged = oldRefundStatus != refundStatus;
        boolean paymentRefundIdNeedUpdate = StringUtils.isNotBlank(paymentRefundId)
                && StringUtils.isBlank(refundRecord.getPaymentRefundId());

        if (!refundStatusChanged && !paymentRefundIdNeedUpdate
                && isOrderRefundStateConsistent(currentOrder, refundStatus)) {
            return true;
        }

        if (refundStatusChanged || paymentRefundIdNeedUpdate) {
            OrderRefundV2 updateRefund = new OrderRefundV2();
            updateRefund.setId(refundRecord.getId());
            updateRefund.setRefundStatus(refundStatus);
            if (paymentRefundIdNeedUpdate) {
                updateRefund.setPaymentRefundId(paymentRefundId);
            }
            updateRefund.setUpdateTime(new Date());
            orderRefundMapper.updateById(updateRefund);
        }

        boolean needUpdateOrder = refundStatusChanged || !isOrderRefundStateConsistent(currentOrder, refundStatus);
        boolean success = true;
        if (needUpdateOrder) {
            OrderV2 order = new OrderV2();
            order.setId(orderId);
            order.setRefundStatus(refundStatus);
            applyOrderRefundState(order, refundStatus);
            order.setUpdateTime(new Date());
            success = orderV2Mapper.updateById(order) > 0;
        }

        if (success && refundStatusChanged) {
            RefundStatusChangeEvent event = new RefundStatusChangeEvent(
                    orderId, currentOrder.getOrderNo(), refundRecord.getId(), resolvedRefundNo,
                    oldRefundStatus, refundStatus, refundRecord.getRefundAmount(),
                    "退款状态更新", null
            );
            orderEventManager.publishRefundStatusChangeEvent(event);
        }

        return success;
    }
    
    @Override
    @Transactional
    public Long createRefundRecord(RefundRequest request) {
        Date now = new Date();

        if (request == null) {
            throw new BaseException("退款请求不能为空");
        }
        if (request.getOrderId() == null) {
            throw new BaseException("订单ID不能为空");
        }
        if (StringUtils.isBlank(request.getRefundNo())) {
            throw new BaseException("退款单号不能为空");
        }
        if (StringUtils.isBlank(request.getRefundType())) {
            throw new BaseException("退款类型不能为空");
        }

        OrderV2 order = orderV2Mapper.selectById(request.getOrderId());
        if (order == null) {
            throw new BaseException("订单不存在");
        }
        if (order.getOrderStatus() == OrderStatus.CANCELLED || order.getPaymentStatus() == PaymentStatus.UNPAID) {
            throw new BaseException("未支付或已取消订单不允许退款");
        }
        if (order.getRefundStatus() == RefundStatus.FULL_REFUND) {
            throw new BaseException("订单已完成退款");
        }

        String refundNo = request.getRefundNo();
        OrderRefundV2 existingRefund = findRefundByNo(refundNo);
        if (existingRefund != null) {
            if (!request.getOrderId().equals(existingRefund.getOrderId())) {
                throw new BaseException("退款单号已存在");
            }
            RefundStatus existingStatus = existingRefund.getRefundStatus() != null
                    ? existingRefund.getRefundStatus()
                    : RefundStatus.REFUND_PROCESSING;
            updateRefundStatus(request.getOrderId(), existingStatus, refundNo, existingRefund.getPaymentRefundId());
            return existingRefund.getId();
        }

        OrderRefundV2 refund = new OrderRefundV2();
        refund.setOrderId(request.getOrderId());
        refund.setRefundNo(refundNo);
        refund.setRefundType(RefundType.fromCode(request.getRefundType()));
        refund.setRefundAmount(request.getRefundAmount());
        refund.setRefundFee(request.getRefundFee());
        refund.setRefundStatus(RefundStatus.REFUND_PROCESSING);
        refund.setRefundReason(request.getRefundReason());
        refund.setRefundDescription(request.getRefundDescription());
        refund.setOperatorRemarks(request.getOperatorRemarks());
        refund.setRefundChannel(request.getRefundChannel());
        refund.setApplyTime(now);
        refund.setCreateTime(now);
        refund.setUpdateTime(now);

        orderRefundMapper.insert(refund);

        updateRefundStatus(request.getOrderId(), RefundStatus.REFUND_PROCESSING, refundNo, null);

        log.info("退款记录创建成功: refundId={}, refundNo={}, orderId={}, refundAmount={}",
                refund.getId(), refundNo, request.getOrderId(), request.getRefundAmount());

        return refund.getId();
    }
    
    @Override
    public PageInfo<OrderV2ListResponse> pageOrdersByUser(OrderV2PageRequest request) {
        // 移动端查询，确保只查询当前用户的订单
        return pageOrders(request);
    }
    
    // ====== 私有辅助方法 ======

    private void validateOrderStatusTransition(OrderV2 currentOrder, OrderStatus targetOrderStatus,
                                              PaymentStatus targetPaymentStatus) {
        if (currentOrder == null || targetOrderStatus == null || targetPaymentStatus == null) {
            throw new BaseException("订单状态参数不能为空");
        }
        OrderStatus currentOrderStatus = currentOrder.getOrderStatus();
        PaymentStatus currentPaymentStatus = currentOrder.getPaymentStatus();
        if (currentOrderStatus == null || currentPaymentStatus == null) {
            throw new BaseException("订单状态异常");
        }
        if (currentOrderStatus == targetOrderStatus && currentPaymentStatus == targetPaymentStatus) {
            return;
        }

        boolean allowed = false;
        if (currentOrderStatus == OrderStatus.PENDING_PAYMENT) {
            allowed = (targetOrderStatus == OrderStatus.PAID && targetPaymentStatus == PaymentStatus.PAID)
                    || (targetOrderStatus == OrderStatus.CANCELLED && targetPaymentStatus == PaymentStatus.UNPAID);
        } else if (currentOrderStatus == OrderStatus.PAID) {
            allowed = (targetOrderStatus == OrderStatus.REFUNDING && targetPaymentStatus == PaymentStatus.PAID)
                    || (targetOrderStatus == OrderStatus.REFUNDED && targetPaymentStatus == PaymentStatus.REFUNDED);
        } else if (currentOrderStatus == OrderStatus.REFUNDING) {
            allowed = targetOrderStatus == OrderStatus.REFUNDED && targetPaymentStatus == PaymentStatus.REFUNDED;
        } else if (currentOrderStatus == OrderStatus.CANCELLED) {
            allowed = targetOrderStatus == OrderStatus.CANCELLED && targetPaymentStatus == PaymentStatus.UNPAID;
        } else if (currentOrderStatus == OrderStatus.REFUNDED) {
            allowed = targetOrderStatus == OrderStatus.REFUNDED && targetPaymentStatus == PaymentStatus.REFUNDED;
        }

        if (!allowed) {
            throw new BaseException("订单状态流转非法");
        }
    }

    private void validatePaymentStatusTransition(OrderV2 currentOrder, PaymentStatus targetPaymentStatus) {
        if (currentOrder == null || targetPaymentStatus == null) {
            throw new BaseException("支付状态参数不能为空");
        }
        if (currentOrder.getOrderStatus() == null || currentOrder.getPaymentStatus() == null) {
            throw new BaseException("订单状态异常");
        }
        if (targetPaymentStatus != PaymentStatus.PAID) {
            throw new BaseException("支付状态仅允许更新为已支付");
        }
        if (currentOrder.getOrderStatus() == OrderStatus.CANCELLED) {
            throw new BaseException("已取消订单不允许支付");
        }
        if (currentOrder.getPaymentStatus() == PaymentStatus.PAID) {
            if (currentOrder.getOrderStatus() == OrderStatus.REFUNDED) {
                throw new BaseException("订单状态不允许支付");
            }
            return;
        }
        if (currentOrder.getPaymentStatus() != PaymentStatus.UNPAID
                || currentOrder.getOrderStatus() != OrderStatus.PENDING_PAYMENT) {
            throw new BaseException("订单状态不允许支付");
        }
    }

    private void validateRefundStatusTransition(OrderV2 currentOrder, RefundStatus targetRefundStatus) {
        if (currentOrder == null || targetRefundStatus == null) {
            throw new BaseException("退款状态参数不能为空");
        }
        if (currentOrder.getOrderStatus() == null || currentOrder.getPaymentStatus() == null) {
            throw new BaseException("订单状态异常");
        }
        if (currentOrder.getOrderStatus() == OrderStatus.CANCELLED) {
            throw new BaseException("已取消订单不允许退款");
        }
        if (currentOrder.getPaymentStatus() == PaymentStatus.UNPAID) {
            throw new BaseException("未支付订单不允许退款");
        }

        RefundStatus currentRefundStatus = currentOrder.getRefundStatus();
        if (currentRefundStatus == null) {
            throw new BaseException("订单退款状态异常");
        }
        if (currentRefundStatus == targetRefundStatus) {
            return;
        }

        boolean allowed = false;
        if (currentRefundStatus == RefundStatus.NO_REFUND) {
            allowed = targetRefundStatus == RefundStatus.REFUND_PROCESSING
                    || targetRefundStatus == RefundStatus.PARTIAL_REFUND
                    || targetRefundStatus == RefundStatus.FULL_REFUND;
        } else if (currentRefundStatus == RefundStatus.REFUND_PROCESSING) {
            allowed = targetRefundStatus == RefundStatus.PARTIAL_REFUND
                    || targetRefundStatus == RefundStatus.FULL_REFUND;
        } else if (currentRefundStatus == RefundStatus.PARTIAL_REFUND) {
            allowed = targetRefundStatus == RefundStatus.FULL_REFUND;
        }

        if (!allowed) {
            throw new BaseException("退款状态流转非法");
        }
    }

    private boolean isOrderRefundStateConsistent(OrderV2 order, RefundStatus refundStatus) {
        if (order == null || refundStatus == null) {
            return false;
        }
        if (refundStatus == RefundStatus.REFUND_PROCESSING || refundStatus == RefundStatus.PARTIAL_REFUND) {
            return order.getOrderStatus() == OrderStatus.REFUNDING
                    && order.getPaymentStatus() == PaymentStatus.PAID;
        }
        if (refundStatus == RefundStatus.FULL_REFUND) {
            return order.getOrderStatus() == OrderStatus.REFUNDED
                    && order.getPaymentStatus() == PaymentStatus.REFUNDED;
        }
        return order.getRefundStatus() == refundStatus;
    }

    private void applyOrderRefundState(OrderV2 order, RefundStatus refundStatus) {
        if (order == null || refundStatus == null) {
            return;
        }
        if (refundStatus == RefundStatus.REFUND_PROCESSING || refundStatus == RefundStatus.PARTIAL_REFUND) {
            order.setOrderStatus(OrderStatus.REFUNDING);
            order.setPaymentStatus(PaymentStatus.PAID);
        } else if (refundStatus == RefundStatus.FULL_REFUND) {
            order.setOrderStatus(OrderStatus.REFUNDED);
            order.setPaymentStatus(PaymentStatus.REFUNDED);
        }
    }

    private OrderRefundV2 resolveRefundRecord(Long orderId, String refundNo) {
        if (StringUtils.isNotBlank(refundNo)) {
            OrderRefundV2 refundRecord = findRefundByNo(refundNo);
            if (refundRecord == null) {
                throw new BaseException("退款单不存在");
            }
            if (!orderId.equals(refundRecord.getOrderId())) {
                throw new BaseException("退款单不存在");
            }
            return refundRecord;
        }

        QueryWrapper<OrderRefundV2> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_id", orderId).orderByDesc("create_time");
        List<OrderRefundV2> refunds = orderRefundMapper.selectList(queryWrapper);
        if (refunds.isEmpty()) {
            throw new BaseException("退款单不存在");
        }
        log.warn("退款单号缺失，使用最新退款记录: orderId={}", orderId);
        return refunds.get(0);
    }

    private OrderRefundV2 findRefundByNo(String refundNo) {
        if (StringUtils.isBlank(refundNo)) {
            return null;
        }
        QueryWrapper<OrderRefundV2> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("refund_no", refundNo);
        return orderRefundMapper.selectOne(queryWrapper);
    }
    
    /**
     * 构建订单查询条件
     */
    private QueryWrapper<OrderV2> buildOrderQueryWrapper(OrderV2PageRequest request) {
        QueryWrapper<OrderV2> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("deleted", 0);
        
        if (request.getOrderNo() != null && !request.getOrderNo().trim().isEmpty()) {
            queryWrapper.like("order_no", request.getOrderNo().trim());
        }
        
        if (request.getMemberId() != null) {
            queryWrapper.eq("member_id", request.getMemberId());
        }
        
        if (request.getScenicId() != null) {
            queryWrapper.eq("scenic_id", request.getScenicId());
        }
        
        if (request.getOrderStatus() != null && !request.getOrderStatus().trim().isEmpty()) {
            queryWrapper.eq("order_status", request.getOrderStatus().trim());
        }
        
        if (request.getPaymentStatus() != null && !request.getPaymentStatus().trim().isEmpty()) {
            queryWrapper.eq("payment_status", request.getPaymentStatus().trim());
        }
        
        if (request.getRefundStatus() != null && !request.getRefundStatus().trim().isEmpty()) {
            queryWrapper.eq("refund_status", request.getRefundStatus().trim());
        }
        
        if (request.getCreateTimeStart() != null) {
            queryWrapper.ge("create_time", request.getCreateTimeStart());
        }
        
        if (request.getCreateTimeEnd() != null) {
            queryWrapper.le("create_time", request.getCreateTimeEnd());
        }
        
        if (request.getPayTimeStart() != null) {
            queryWrapper.ge("pay_time", request.getPayTimeStart());
        }
        
        if (request.getPayTimeEnd() != null) {
            queryWrapper.le("pay_time", request.getPayTimeEnd());
        }
        
        queryWrapper.orderByDesc("create_time");
        
        return queryWrapper;
    }
    
    /**
     * 转换为列表响应DTO
     */
    private OrderV2ListResponse convertToListResponse(OrderV2 order) {
        OrderV2ListResponse response = new OrderV2ListResponse();
        response.setId(order.getId());
        response.setOrderNo(order.getOrderNo());
        response.setMemberId(order.getMemberId());
        response.setOpenId(order.getOpenId());
        response.setFaceId(order.getFaceId());
        response.setScenicId(order.getScenicId());
        response.setOriginalAmount(order.getOriginalAmount());
        response.setDiscountAmount(order.getDiscountAmount());
        response.setFinalAmount(order.getFinalAmount());
        response.setOrderStatus(order.getOrderStatus());
        response.setOrderStatusDesc(order.getOrderStatus().getDescription());
        response.setPaymentStatus(order.getPaymentStatus());
        response.setPaymentStatusDesc(order.getPaymentStatus().getDescription());
        response.setRefundStatus(order.getRefundStatus());
        response.setRefundStatusDesc(order.getRefundStatus().getDescription());
        response.setTotalRefundAmount(order.getTotalRefundAmount());
        response.setRemarks(order.getRemarks());
        response.setPayTime(order.getPayTime());
        response.setCompleteTime(order.getCompleteTime());
        response.setCreateTime(order.getCreateTime());
        response.setUpdateTime(order.getUpdateTime());
        
        // 查询商品数量信息
        QueryWrapper<OrderItemV2> itemQuery = new QueryWrapper<>();
        itemQuery.eq("order_id", order.getId());
        List<OrderItemV2> items = orderItemMapper.selectList(itemQuery);
        response.setItemCount(items.size());
        response.setTotalQuantity(items.stream().mapToInt(OrderItemV2::getQuantity).sum());
        
        return response;
    }
    
    /**
     * 转换为详情响应DTO
     */
    private OrderV2DetailResponse convertToDetailResponse(OrderV2 order, 
                                                         List<OrderItemV2> orderItems,
                                                         List<OrderDiscountV2> orderDiscounts,
                                                         List<OrderRefundV2> orderRefunds) {
        OrderV2DetailResponse response = new OrderV2DetailResponse();
        response.setId(order.getId());
        response.setOrderNo(order.getOrderNo());
        response.setMemberId(order.getMemberId());
        response.setOpenId(order.getOpenId());
        response.setFaceId(order.getFaceId());
        response.setScenicId(order.getScenicId());
        response.setOriginalAmount(order.getOriginalAmount());
        response.setDiscountAmount(order.getDiscountAmount());
        response.setFinalAmount(order.getFinalAmount());
        response.setOrderStatus(order.getOrderStatus());
        response.setOrderStatusDesc(order.getOrderStatus().getDescription());
        response.setPaymentStatus(order.getPaymentStatus());
        response.setPaymentStatusDesc(order.getPaymentStatus().getDescription());
        response.setRefundStatus(order.getRefundStatus());
        response.setRefundStatusDesc(order.getRefundStatus().getDescription());
        response.setTotalRefundAmount(order.getTotalRefundAmount());
        response.setRemarks(order.getRemarks());
        response.setPayTime(order.getPayTime());
        response.setCompleteTime(order.getCompleteTime());
        response.setCreateTime(order.getCreateTime());
        response.setUpdateTime(order.getUpdateTime());
        response.setCreateBy(order.getCreateBy());
        response.setUpdateBy(order.getUpdateBy());
        
        response.setOrderItems(orderItems);
        response.setOrderDiscounts(orderDiscounts);
        response.setOrderRefunds(orderRefunds);
        
        return response;
    }
    
    /**
     * 生成退款单号
     */
    private String generateRefundNo() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String timestamp = sdf.format(new Date());
        int random = (int) (Math.random() * 900) + 100;
        return "REFUND" + timestamp + random;
    }
    
    // ====== 支付相关方法实现 ======
    
    @Override
    public PaymentParamsResponse getPaymentParams(Long orderId, Long userId, PaymentParamsRequest request) {
        log.info("获取支付参数: orderId={}, userId={}", orderId, userId);
        
        // 1. 查询订单
        OrderV2 order = orderV2Mapper.selectById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        
        // 2. 验证订单权限
        if (!userId.equals(order.getMemberId())) {
            throw new RuntimeException("无权获取该订单的支付参数");
        }
        
        // 3. 验证订单状态
        if (order.getOrderStatus() != OrderStatus.PENDING_PAYMENT
                || order.getPaymentStatus() != PaymentStatus.UNPAID) {
            throw new BaseException("订单状态不允许支付");
        }
        
        // 4. 获取用户openId（从订单中获取）
        String openId = order.getOpenId();
        if (openId == null || openId.trim().isEmpty()) {
            throw new RuntimeException("用户openId不存在，无法发起支付");
        }
        
        // 5. 检查是否为免费订单
        if (order.getFinalAmount().compareTo(BigDecimal.ZERO) == 0) {
            log.info("免费订单，无需支付: orderId={}", orderId);
            return PaymentParamsResponse.free(orderId, order.getOrderNo());
        }
        
        // 6. 获取景区支付适配器
        IPayAdapter payAdapter = scenicService.getScenicPayAdapter(order.getScenicId());
        
        try {
            // 7. 生成商品名称和描述
            String goodsName = generateGoodsName(orderId);
            String description = goodsName; // 直接使用商品名称作为描述
            
            // 8. 创建支付订单请求
            CreateOrderRequest payRequest = new CreateOrderRequest()
                    .setOrderNo(order.getOrderNo())
                    .setPriceInCents(order.getFinalAmount().multiply(BigDecimal.valueOf(100)).intValue())
                    .setDescription(description)
                    .setGoodsName(goodsName)
                    .setUserIdentify(openId)
                    .setNotifyUrl("https://zhentuai.com/api/mobile/order/v2/payment/callback/" + order.getScenicId());
            
            // 9. 调用支付适配器创建订单
            CreateOrderResponse payResponse = payAdapter.createOrder(payRequest);
            
            // 10. 获取支付参数
            java.util.Map<String, Object> paymentParams = payAdapter.getPaymentParams(payResponse);
            
            // 11. 构建响应
            PaymentParamsResponse response = PaymentParamsResponse.success(
                orderId, 
                order.getOrderNo(), 
                order.getFinalAmount(),
                !payResponse.isSkipPay(),
                paymentParams
            );
            response.setDescription(description);
            response.setGoodsName(goodsName);
            
            log.info("支付参数生成成功: orderId={}, needPay={}, amount={}", 
                    orderId, !payResponse.isSkipPay(), order.getFinalAmount());
            
            return response;
            
        } catch (Exception e) {
            log.error("获取支付参数失败: orderId={}, error={}", orderId, e.getMessage(), e);
            throw new RuntimeException("获取支付参数失败: " + e.getMessage());
        }
    }
    
    @Override
    public PaymentCallbackResponse handlePaymentCallback(Long scenicId, HttpServletRequest request) {
        log.info("处理支付回调: scenicId={}", scenicId);
        
        try {
            // 1. 获取支付适配器
            IPayAdapter payAdapter = scenicService.getScenicPayAdapter(scenicId);
            
            // 2. 解析回调数据
            PayResponse callbackResponse = payAdapter.handleCallback(request);
            log.info("解析支付回调数据: {}", callbackResponse);
            
            if (callbackResponse == null || callbackResponse.getOrderNo() == null) {
                return PaymentCallbackResponse.failure("回调数据解析失败");
            }
            
            // 3. 查询订单
            String orderNo = callbackResponse.getOrderNo();
            OrderV2 order = getByOrderNo(orderNo);
            if (order == null) {
                return PaymentCallbackResponse.failure("订单不存在", null, orderNo);
            }
            
            // 4. 处理不同的支付状态变更
            String statusChangeType = null;
            if (callbackResponse.isPay()) {
                // 支付成功
                statusChangeType = "PAID";
                updatePaymentStatus(order.getId(), PaymentStatus.PAID.getCode());
            } else if (callbackResponse.isCancel()) {
                // 支付取消
                statusChangeType = "CANCELLED";
                updateOrderStatus(order.getId(), OrderStatus.CANCELLED.getCode(), PaymentStatus.UNPAID.getCode());
            } else if (callbackResponse.isRefund()) {
                // 退款
                statusChangeType = "REFUNDED";
                updateRefundStatus(order.getId(), RefundStatus.FULL_REFUND, null, callbackResponse.getTransactionId());
            }
            
            log.info("支付回调处理成功: orderId={}, orderNo={}, statusChangeType={}", 
                    order.getId(), orderNo, statusChangeType);
            
            return PaymentCallbackResponse.success(order.getId(), orderNo, statusChangeType);
            
        } catch (Exception e) {
            log.error("处理支付回调失败: scenicId={}, error={}", scenicId, e.getMessage(), e);
            return PaymentCallbackResponse.failure("回调处理失败: " + e.getMessage());
        }
    }
    
    /**
     * 生成商品名称
     * 根据订单的商品类型生成用于支付页面展示的商品名称
     * 如果是一种商品类型，显示具体类型名称；如果是多种，显示"多项景区商品"
     */
    private String generateGoodsName(Long orderId) {
        // 查询订单商品明细
        QueryWrapper<OrderItemV2> itemQuery = new QueryWrapper<>();
        itemQuery.eq("order_id", orderId);
        java.util.List<OrderItemV2> orderItems = orderItemMapper.selectList(itemQuery);
        
        if (orderItems.isEmpty()) {
            return "景区商品";
        }
        
        // 获取所有不同的商品类型
        java.util.Set<String> productTypes = new java.util.HashSet<>();
        for (OrderItemV2 item : orderItems) {
            productTypes.add(item.getProductType());
        }
        
        // 如果只有一种商品类型，返回具体类型名称
        if (productTypes.size() == 1) {
            String productType = productTypes.iterator().next();
            return getProductTypeName(productType);
        } else {
            // 如果有多种商品类型，返回通用名称
            return "多项景区商品";
        }
    }
    
    /**
     * 获取商品类型中文名称
     * 重构: 从配置驱动替代硬编码
     */
    private String getProductTypeName(String productType) {
        return productTypeCapabilityService.getDisplayName(productType);
    }
    
    /**
     * 商品价格和名称信息内部DTO
     */
    private static class ProductPriceAndNameInfo {
        private BigDecimal unitPrice;
        private BigDecimal originalPrice;
        private String productName;
        
        public ProductPriceAndNameInfo(BigDecimal unitPrice, BigDecimal originalPrice, String productName) {
            this.unitPrice = unitPrice;
            this.originalPrice = originalPrice;
            this.productName = productName;
        }
        
        public BigDecimal getUnitPrice() { return unitPrice; }
        public BigDecimal getOriginalPrice() { return originalPrice; }
        public String getProductName() { return productName; }
    }
    
    /**
     * 重新计算商品价格信息并获取商品名称
     * 基于定价配置重新计算商品的单价、原价和商品名称
     */
    private ProductPriceAndNameInfo calculateProductItemPriceAndName(ProductItem product) {
        String productTypeCode = product.getProductType().getCode();
        String productId = product.getProductId() != null ? product.getProductId() : "default";
        
        BigDecimal unitPrice;
        BigDecimal originalPrice;
        String productName;
        
        try {
            // 1. 优先使用基于product_id的阶梯定价
            PriceTierConfig tierConfig = productConfigService.getTierConfig(
                    productTypeCode, productId, product.getQuantity());
            
            if (tierConfig != null) {
                unitPrice = tierConfig.getPrice();
                originalPrice = tierConfig.getOriginalPrice();
                
                // 阶梯定价没有商品名称，需要从基础配置获取
                PriceProductConfig baseConfig = productConfigService.getProductConfig(productTypeCode, productId);
                productName = (baseConfig != null && baseConfig.getProductName() != null) 
                    ? baseConfig.getProductName() 
                    : getProductTypeName(product.getProductType().name());
                
                log.debug("使用阶梯定价: productType={}, productId={}, quantity={}, price={}, originalPrice={}, productName={}", 
                        productTypeCode, productId, product.getQuantity(), unitPrice, originalPrice, productName);
            } else {
                // 2. 使用基于product_id的基础配置
                PriceProductConfig baseConfig;
                try {
                    baseConfig = productConfigService.getProductConfig(productTypeCode, productId);
                } catch (Exception e) {
                    log.warn("未找到具体商品配置: productType={}, productId={}, 使用default配置", 
                            productTypeCode, productId);
                    baseConfig = productConfigService.getProductConfig(productTypeCode, "default");
                }
                
                if (baseConfig == null) {
                    throw new PriceCalculationException(
                            String.format("未找到商品价格配置: productType=%s, productId=%s", productTypeCode, productId));
                }
                
                unitPrice = baseConfig.getBasePrice();
                originalPrice = baseConfig.getOriginalPrice();
                productName = (baseConfig.getProductName() != null) 
                    ? baseConfig.getProductName() 
                    : getProductTypeName(product.getProductType().name());
                
                // 3. 处理按数量计价的商品类型
                // 重构: 使用商品类型能力配置替代硬编码判断
                ProductTypeCapability capability = productTypeCapabilityService.getCapability(productTypeCode);
                if (capability.getPricingModeEnum() == PricingMode.QUANTITY_BASED) {
                    Integer quantity = product.getQuantity() != null && product.getQuantity() > 0
                            ? product.getQuantity() : 1;
                    unitPrice = unitPrice.multiply(BigDecimal.valueOf(quantity));
                    if (originalPrice != null) {
                        originalPrice = originalPrice.multiply(BigDecimal.valueOf(quantity));
                    }
                    log.debug("按数量计价: productType={}, quantity={}, unitPrice={}",
                            productTypeCode, quantity, unitPrice);
                }
            }
            
            // 4. 设置计算后的价格到ProductItem
            product.setUnitPrice(unitPrice);
            product.setOriginalPrice(originalPrice != null ? originalPrice : unitPrice);
            
            // 5. 计算小计（单价 × 购买数量）
            int purchaseCount = product.getPurchaseCount() != null ? product.getPurchaseCount() : 1;
            BigDecimal subtotal = unitPrice.multiply(BigDecimal.valueOf(purchaseCount));
            product.setSubtotal(subtotal);
            
            log.debug("商品价格和名称计算完成: productType={}, productId={}, unitPrice={}, originalPrice={}, subtotal={}, productName={}", 
                    productTypeCode, productId, unitPrice, originalPrice, subtotal, productName);
            
            return new ProductPriceAndNameInfo(unitPrice, originalPrice != null ? originalPrice : unitPrice, productName);
                    
        } catch (Exception e) {
            log.error("计算商品价格失败: productType={}, productId={}, error={}", 
                    productTypeCode, productId, e.getMessage(), e);
            
            // 兜底处理：使用默认价格和类型名称
            BigDecimal defaultPrice = BigDecimal.ZERO;
            String fallbackName = getProductTypeName(product.getProductType().name());
            
            product.setUnitPrice(defaultPrice);
            product.setOriginalPrice(defaultPrice);
            product.setSubtotal(defaultPrice);
            
            return new ProductPriceAndNameInfo(defaultPrice, defaultPrice, fallbackName);
        }
    }
    
    /**
     * 检查重复购买
     * 防止用户重复购买相同内容
     * 重构: 使用策略模式替代硬编码的 switch-case
     *
     * @param userId 用户ID
     * @param faceId 人脸ID
     * @param scenicId 景区ID
     * @param products 商品列表
     * @throws DuplicatePurchaseException 如果检测到重复购买
     */
    private void checkDuplicatePurchase(Long userId, Long faceId, Long scenicId, List<ProductItem> products) {
        for (ProductItem product : products) {
            String productType = product.getProductType().getCode();

            // 获取商品类型能力配置
            ProductTypeCapability capability = productTypeCapabilityService.getCapability(productType);

            // 如果允许重复购买，直接跳过
            if (Boolean.TRUE.equals(capability.getAllowDuplicatePurchase())) {
                log.debug("商品类型允许重复购买，跳过检查: productType={}, productId={}",
                        productType, product.getProductId());
                continue;
            }

            // 获取检查策略并执行
            DuplicateCheckStrategy strategy = capability.getDuplicateCheckStrategyEnum();
            if (strategy != null && strategy != DuplicateCheckStrategy.NO_CHECK) {
                try {
                    IDuplicatePurchaseChecker checker = duplicatePurchaseCheckerFactory.getChecker(strategy);

                    // 构建检查上下文
                    DuplicateCheckContext context = new DuplicateCheckContext();
                    context.setUserId(String.valueOf(userId));
                    context.setScenicId(String.valueOf(scenicId));
                    context.setProductType(productType);
                    context.setProductId(product.getProductId());
                    context.setProducts(products);
                    context.addParam("faceId", faceId);

                    // 执行检查
                    checker.check(context);
                } catch (DuplicatePurchaseException e) {
                    // 重新抛出重复购买异常
                    throw e;
                } catch (Exception e) {
                    log.error("重复购买检查失败，策略: {}, productType: {}", strategy, productType, e);
                    // 检查失败时为了安全起见，默认拒绝
                    throw new BaseException("重复购买检查失败，请稍后重试");
                }
            }
        }
    }
}
