package com.example.demo.service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.example.demo.model.Order;
import com.example.demo.model.OrderItem;
import com.example.demo.model.OrderStatus;
import com.example.demo.model.OrderType;
import com.example.demo.model.User;
import com.example.demo.model.MembershipLevel;
import com.example.demo.model.UserMembership;
import com.example.demo.repository.OrderItemRepository;
import com.example.demo.repository.OrderRepository;
import com.example.demo.repository.MembershipLevelRepository;
import com.example.demo.repository.UserMembershipRepository;

@Service
@Transactional
public class OrderService {
    
    private static final Logger logger = LoggerFactory.getLogger(OrderService.class);
    
    @Autowired
    private OrderRepository orderRepository;
    
    @Autowired
    private OrderItemRepository orderItemRepository;
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private SystemSettingsService systemSettingsService;
    
    @Autowired
    private MembershipLevelRepository membershipLevelRepository;
    
    @Autowired
    private UserMembershipRepository userMembershipRepository;
    
    
    /**
     * 创建订单
     */
    public Order createOrder(Order order) {
        try {
            // 设置订单状态
            if (order.getStatus() == null) {
                order.setStatus(OrderStatus.PENDING);
            }
            
            // 设置默认货币
            if (order.getCurrency() == null || order.getCurrency().isEmpty()) {
                order.setCurrency("CNY");
            }
            
            // 设置默认订单类型
            if (order.getOrderType() == null) {
                order.setOrderType(OrderType.PRODUCT);
            }
            
            // 计算订单总金额
            if (order.getOrderItems() != null && !order.getOrderItems().isEmpty()) {
                BigDecimal totalAmount = order.getOrderItems().stream()
                        .map(OrderItem::getSubtotal)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
                order.setTotalAmount(totalAmount);
            }
            
            // 临时保存订单项，避免级联保存问题
            List<OrderItem> tempOrderItems = order.getOrderItems();
            order.setOrderItems(new ArrayList<>()); // 清空订单项
            
            // 先保存订单（获得ID）
            Order savedOrder = orderRepository.save(order);
            
            // 再保存订单项，设置正确的order_id
            if (tempOrderItems != null && !tempOrderItems.isEmpty()) {
                List<OrderItem> savedOrderItems = new ArrayList<>();
                for (OrderItem item : tempOrderItems) {
                    item.setOrder(savedOrder); // 设置关联的订单
                    OrderItem savedItem = orderItemRepository.save(item);
                    savedOrderItems.add(savedItem);
                }
                savedOrder.setOrderItems(savedOrderItems);
            }
            
            logger.info("订单创建成功，订单号：{}", savedOrder.getOrderNumber());
            return savedOrder;
            
        } catch (Exception e) {
            logger.error("创建订单失败：", e);
            throw new RuntimeException("创建订单失败：" + e.getMessage());
        }
    }
    
    /**
     * 根据ID查找订单
     */
    @Transactional(readOnly = true)
    public Optional<Order> findById(Long id) {
        return orderRepository.findById(id);
    }
    
    /**
     * 根据订单号查找订单
     */
    @Transactional(readOnly = true)
    public Optional<Order> findByOrderNumber(String orderNumber) {
        return orderRepository.findByOrderNumber(orderNumber);
    }
    
    /**
     * 根据用户ID查找订单
     */
    @Transactional(readOnly = true)
    public List<Order> findByUserId(Long userId) {
        return orderRepository.findByUserId(userId);
    }
    
    /**
     * 根据用户ID分页查找订单
     */
    @Transactional(readOnly = true)
    public Page<Order> findByUserId(Long userId, Pageable pageable) {
        return orderRepository.findByUserId(userId, pageable);
    }
    
    /**
     * 查找所有订单
     */
    @Transactional(readOnly = true)
    public List<Order> findAll() {
        return orderRepository.findAll();
    }
    
    /**
     * 分页查找所有订单
     */
    @Transactional(readOnly = true)
    public Page<Order> findAll(Pageable pageable) {
        return orderRepository.findAll(pageable);
    }
    
    /**
     * 根据状态查找订单
     */
    @Transactional(readOnly = true)
    public List<Order> findByStatus(OrderStatus status) {
        return orderRepository.findByStatus(status);
    }
    
    /**
     * 根据状态分页查找订单
     */
    @Transactional(readOnly = true)
    public Page<Order> findByStatus(OrderStatus status, Pageable pageable) {
        return orderRepository.findByStatus(status, pageable);
    }
    
    /**
     * 更新订单状态
     */
    public Order updateOrderStatus(Long orderId, OrderStatus newStatus) {
        try {
            // 使用findByIdWithUser确保加载用户信息，用于积分处理
            Order order = orderRepository.findByIdWithUser(orderId)
                    .orElseThrow(() -> new RuntimeException("订单不存在：" + orderId));
            
            OrderStatus oldStatus = order.getStatus();
            order.setStatus(newStatus);
            
            // 设置相应的时间戳
            LocalDateTime now = LocalDateTime.now();
            switch (newStatus) {
                case PENDING:
                    // 待处理状态，不需要设置时间戳
                    break;
                case CONFIRMED:
                    // 已确认状态，不需要设置时间戳
                    break;
                case PROCESSING:
                    // 处理中状态，不需要设置时间戳
                    break;
                case PAID:
                    order.setPaidAt(now);
                    break;
                case SHIPPED:
                    order.setShippedAt(now);
                    break;
                case DELIVERED:
                    order.setDeliveredAt(now);
                    break;
                case COMPLETED:
                    order.setDeliveredAt(now);
                    break;
                case CANCELLED:
                    order.setCancelledAt(now);
                    break;
                case REFUNDED:
                    break;
                default:
                    // 其他状态，不需要设置时间戳
                    break;
            }
            
            Order updatedOrder = orderRepository.save(order);
            logger.info("订单状态更新成功，订单号：{}，状态：{} -> {}", 
                order.getOrderNumber(), oldStatus, newStatus);
            
            // 处理积分变更
            handlePointsForStatusChange(order, oldStatus, newStatus);
            
            return updatedOrder;
            
        } catch (Exception e) {
            logger.error("更新订单状态失败：", e);
            throw new RuntimeException("更新订单状态失败：" + e.getMessage());
        }
    }
    
    /**
     * 根据订单状态变更处理用户积分
     * PENDING/CANCELLED/REFUNDED -> PAID: 增加积分
     * PAID -> CANCELLED/REFUNDED: 扣除积分
     */
    private void handlePointsForStatusChange(Order order, OrderStatus oldStatus, OrderStatus newStatus) {
        if (order == null || order.getUser() == null) {
            logger.warn("handlePointsForStatusChange: order或user为空");
            return;
        }
        
        User user = order.getUser();
        logger.info("handlePointsForStatusChange: userId={}, orderId={}, oldStatus={}, newStatus={}", 
            user.getId(), order.getId(), oldStatus, newStatus);
        
        // 从非PAID状态变为PAID状态：增加积分并更新会员等级
        if (newStatus == OrderStatus.PAID && oldStatus != OrderStatus.PAID) {
            // 先更新会员等级和到期时间（无论积分是否为0都要更新）
            try {
                updateMembershipForOrder(order, user);
            } catch (Exception e) {
                logger.error("更新会员等级失败: userId={}, orderId={}", user.getId(), order.getId(), e);
            }
            
            // 再处理积分
            int points = getPointsFromOrderMembershipLevel(order);
            if (points > 0) {
                try {
                    userService.addPoints(user.getId(), points);
                    logger.info("订单状态变更增加积分: userId={}, orderId={}, points={}", 
                        user.getId(), order.getId(), points);
                } catch (Exception e) {
                    logger.error("增加积分失败: userId={}, orderId={}, points={}", user.getId(), order.getId(), points, e);
                }
            } else {
                logger.warn("积分为0，跳过积分增加: userId={}, orderId={}", user.getId(), order.getId());
            }
        }
        
        // 从PAID状态变为CANCELLED或REFUNDED状态：扣除积分
        if ((newStatus == OrderStatus.CANCELLED || newStatus == OrderStatus.REFUNDED) && oldStatus == OrderStatus.PAID) {
            int points = getPointsFromOrderMembershipLevel(order);
            if (points > 0) {
                try {
                    userService.deductPoints(user.getId(), points);
                    logger.info("订单状态变更扣除积分: userId={}, orderId={}, points={}", 
                        user.getId(), order.getId(), points);
                } catch (Exception e) {
                    logger.error("扣除积分失败: userId={}, orderId={}, points={}", user.getId(), order.getId(), points, e);
                }
            }
        }
    }
    
    /**
     * 根据订单描述或金额获取对应会员等级的积分（完全动态，从数据库获取所有会员等级进行匹配）
     */
    private int getPointsFromOrderMembershipLevel(Order order) {
        String description = order.getDescription();
        
        // 从数据库获取所有会员等级
        List<MembershipLevel> allLevels = membershipLevelRepository.findAll();
        
        // 1. 首先尝试从描述匹配
        if (description != null && !description.isEmpty()) {
            String descLower = description.toLowerCase();
            
            for (MembershipLevel level : allLevels) {
                String name = level.getName();
                String displayName = level.getDisplayName();
                
                // 检查订单描述是否包含会员等级的name或displayName（不区分大小写）
                if ((name != null && descLower.contains(name.toLowerCase())) ||
                    (displayName != null && descLower.contains(displayName.toLowerCase()))) {
                    logger.info("从订单描述匹配到会员等级: level={}, points={}", name, level.getPointsBonus());
                    return level.getPointsBonus();
                }
                
                // 额外匹配中文关键词
                if (name != null) {
                    if (name.equals("standard") && (description.contains("标准") || description.contains("Standard"))) {
                        logger.info("从订单描述匹配到会员等级(中文): level={}, points={}", name, level.getPointsBonus());
                        return level.getPointsBonus();
                    }
                    if (name.equals("professional") && (description.contains("专业") || description.contains("Professional") || description.contains("Pro"))) {
                        logger.info("从订单描述匹配到会员等级(中文): level={}, points={}", name, level.getPointsBonus());
                        return level.getPointsBonus();
                    }
                    if (name.equals("starter") && (description.contains("入门") || description.contains("Starter"))) {
                        logger.info("从订单描述匹配到会员等级(中文): level={}, points={}", name, level.getPointsBonus());
                        return level.getPointsBonus();
                    }
                    if (name.equals("free") && (description.contains("免费") || description.contains("Free"))) {
                        logger.info("从订单描述匹配到会员等级(中文): level={}, points={}", name, level.getPointsBonus());
                        return level.getPointsBonus();
                    }
                }
            }
        }
        
        // 2. 描述为空或无法匹配时，使用金额判断
        BigDecimal amount = order.getTotalAmount();
        if (amount != null) {
            int amountInt = amount.intValue();
            logger.info("订单描述为空或无法匹配，尝试使用金额判断: amount={}", amountInt);
            
            // 按价格从高到低排序，优先匹配高价套餐
            allLevels.sort((a, b) -> {
                Double priceA = a.getPrice() != null ? a.getPrice() : 0.0;
                Double priceB = b.getPrice() != null ? b.getPrice() : 0.0;
                return priceB.compareTo(priceA);
            });
            
            for (MembershipLevel level : allLevels) {
                if (level.getPrice() == null || level.getPrice() <= 0) continue;
                int levelPrice = level.getPrice().intValue();
                
                // 允许10%的价格浮动
                if (amountInt >= levelPrice * 0.9 && amountInt <= levelPrice * 1.1) {
                    logger.info("从订单金额匹配到会员等级: level={}, price={}, amount={}, points={}", 
                        level.getName(), levelPrice, amountInt, level.getPointsBonus());
                    return level.getPointsBonus();
                }
            }
            
            logger.warn("无法从订单金额匹配会员等级: amount={}", amountInt);
        }
        
        logger.warn("无法从订单识别会员等级: description={}, amount={}", description, amount);
        return 0;
    }
    
    /**
     * 根据订单金额计算对应的积分
     */
    private int calculatePointsForAmount(BigDecimal amount) {
        if (amount == null) return 0;
        
        // 从membership_levels表读取价格和积分（必须从数据库获取，禁止硬编码）
        MembershipLevel starterLevel = membershipLevelRepository.findByName("starter")
            .orElseThrow(() -> new IllegalStateException("数据库中缺少starter会员等级配置"));
        MembershipLevel standardLevel = membershipLevelRepository.findByName("standard")
            .orElseThrow(() -> new IllegalStateException("数据库中缺少standard会员等级配置"));
        MembershipLevel proLevel = membershipLevelRepository.findByName("professional")
            .orElseThrow(() -> new IllegalStateException("数据库中缺少professional会员等级配置"));
        
        int starterPrice = starterLevel.getPrice().intValue();
        int starterPoints = starterLevel.getPointsBonus();
        int standardPrice = standardLevel.getPrice().intValue();
        int standardPoints = standardLevel.getPointsBonus();
        int proPrice = proLevel.getPrice().intValue();
        int proPoints = proLevel.getPointsBonus();
        
        int amountInt = amount.intValue();
        
        // 判断套餐类型：先高后低（专业版 > 标准版 > 入门版）
        if (amountInt >= proPrice * 0.9 && amountInt <= proPrice * 1.1) {
            return proPoints;  // 专业版积分
        } else if (amountInt >= standardPrice * 0.9 && amountInt <= standardPrice * 1.1) {
            return standardPoints;   // 标准版积分
        } else if (amountInt >= starterPrice * 0.9 && amountInt <= starterPrice * 1.1) {
            return starterPoints;    // 入门版积分
        } else if (amountInt >= proPrice) {
            return proPoints;
        } else if (amountInt >= standardPrice) {
            return standardPoints;
        } else if (amountInt >= starterPrice) {
            return starterPoints;
        }
        
        return 0;
    }
    
    /**
     * 根据订单信息更新用户会员等级和到期时间
     */
    private void updateMembershipForOrder(Order order, User user) {
        try {
            String description = order.getDescription();
            if (description == null || description.isEmpty()) {
                logger.info("订单描述为空，不更新会员: userId={}", user.getId());
                return;
            }
            
            logger.info("开始匹配会员等级，订单描述: {}", description);
            
            // 从数据库获取所有会员等级，动态匹配
            MembershipLevel level = null;
            List<MembershipLevel> allLevels = membershipLevelRepository.findAll();
            
            // 优先匹配中文关键词（更精确）
            for (MembershipLevel lvl : allLevels) {
                String name = lvl.getName();
                if (name == null) continue;
                
                // 免费版（free）也参与匹配：用于免费版可能启用付费/期限时的开通链路
                
                // 匹配中文关键词
                if ("standard".equalsIgnoreCase(name) && description.contains("标准")) {
                    level = lvl;
                    logger.info("匹配到标准版会员: levelId={}, name={}", lvl.getId(), name);
                    break;
                }
                if ("professional".equalsIgnoreCase(name) && (description.contains("专业") || description.contains("Pro"))) {
                    level = lvl;
                    logger.info("匹配到专业版会员: levelId={}, name={}", lvl.getId(), name);
                    break;
                }
                if ("starter".equalsIgnoreCase(name) && (description.contains("入门") || description.contains("Starter"))) {
                    level = lvl;
                    logger.info("匹配到入门版会员: levelId={}, name={}", lvl.getId(), name);
                    break;
                }
                if ("free".equalsIgnoreCase(name) && (description.contains("免费") || description.contains("Free"))) {
                    level = lvl;
                    logger.info("匹配到免费版会员: levelId={}, name={}", lvl.getId(), name);
                    break;
                }
                
                // 匹配 displayName
                String displayName = lvl.getDisplayName();
                if (displayName != null && description.contains(displayName)) {
                    level = lvl;
                    logger.info("通过displayName匹配到会员: levelId={}, displayName={}", lvl.getId(), displayName);
                    break;
                }
            }
            
            if (level == null) {
                logger.info("无法从订单描述中识别会员等级，不更新会员: userId={}, description={}", user.getId(), description);
                return;
            }
            int durationDays = level.getDurationDays();
            logger.info("会员等级匹配成功: level={}, durationDays={}", level.getName(), durationDays);
            
            // 查找或创建用户会员信息（按到期时间降序，返回最新的）
            Optional<UserMembership> membershipOpt = userMembershipRepository.findFirstByUserIdAndStatusOrderByEndDateDesc(user.getId(), "ACTIVE");
            
            UserMembership membership;
            LocalDateTime now = LocalDateTime.now();
            
            if (membershipOpt.isPresent()) {
                membership = membershipOpt.get();
                logger.info("找到现有会员记录: membershipId={}, currentEndDate={}", membership.getId(), membership.getEndDate());
                
                // 从数据库获取当前会员等级的价格，用价格判断等级高低（价格越高等级越高）
                // 会员等级只能升不能降：专业版 > 标准版 > 入门版 > 免费版
                Optional<MembershipLevel> currentLevelOpt = membershipLevelRepository.findById(membership.getMembershipLevelId());
                Double currentPrice = currentLevelOpt.isPresent() ? currentLevelOpt.get().getPrice() : 0.0;
                Double newPrice = level.getPrice() != null ? level.getPrice() : 0.0;

                // 延长到期时间（先计算，后面都会用到）
                LocalDateTime currentEndDate = membership.getEndDate();
                LocalDateTime newEndDate;
                
                // 🔥 判断是否是新用户/永久会员：通过到期时间是否为2099年来判断
                // 永久会员（endDate=2099年）在首次购买时，应从现在开始计算，而不是在2099年基础上延长
                boolean isPermanentMember = currentEndDate != null && currentEndDate.getYear() >= 2099;
                
                if (isPermanentMember) {
                    // 永久会员（免费会员）首次购买：从现在开始计算，而不是在2099年基础上延长
                    newEndDate = now.plusDays(durationDays);
                    logger.info("🎉 检测到永久会员首次购买，从现在开始计算: {} + {}天 = {}", now, durationDays, newEndDate);
                } else if (currentEndDate != null && currentEndDate.isAfter(now)) {
                    // 老用户纭费且未过期：在当前到期时间基础上延长
                    newEndDate = currentEndDate.plusDays(durationDays);
                    logger.info("🔄 用户续费，在现有基础上延长: {} + {}天 = {}", currentEndDate, durationDays, newEndDate);
                } else {
                    // 已过期：从现在开始计算
                    newEndDate = now.plusDays(durationDays);
                    logger.info("⏰ 会员已过期，从现在开始计算: {} + {}天 = {}", now, durationDays, newEndDate);
                }

                // 如果用户当前是更高等级，允许低价续费但保持当前等级
                if (newPrice < currentPrice) {
                    logger.info("🔥 检测到低价套餐，保持当前等级但延长到期时间: currentPrice={}, newPrice={}, currentLevel={}, requestedLevel={}, newEndDate={}",
                        currentPrice, newPrice, currentLevelOpt.isPresent() ? currentLevelOpt.get().getName() : "unknown", level.getName(), newEndDate);
                    // 不更新会员等级，但延长到期时间
                    membership.setEndDate(newEndDate);
                    logger.info("✅ 低价续费成功: 保持{}等级，延长到期至 {}", 
                        currentLevelOpt.isPresent() ? currentLevelOpt.get().getDisplayName() : "当前", newEndDate);
                } else if (newPrice >= currentPrice) {
                    // 🔥 价格大于等于当前等级时，更新会员等级并延长时间
                    membership.setMembershipLevelId(level.getId());
                    membership.setEndDate(newEndDate);
                    if (newPrice > currentPrice) {
                        logger.info("⬆️ 会员等级升级: 旧价格={}, 新价格={}, 设置为{}, 延长到期至 {}", 
                            currentPrice, newPrice, level.getName(), newEndDate);
                    } else {
                        logger.info("🔄 会员等级续费: 价格={}, 设置为{}, 延长到期至 {}", 
                            newPrice, level.getName(), newEndDate);
                    }
                }
            } else {
                // 创建新的会员记录
                logger.info("未找到现有会员记录，创建新记录");
                membership = new UserMembership();
                membership.setUserId(user.getId());
                membership.setMembershipLevelId(level.getId());
                membership.setStartDate(now);
                membership.setEndDate(now.plusDays(durationDays));
                membership.setStatus("ACTIVE");
                logger.info("新会员记录: startDate={}, endDate={}", now, membership.getEndDate());
            }
            
            membership.setUpdatedAt(now);
            userMembershipRepository.save(membership);
            
            logger.info("✅ 更新用户会员信息成功: userId={}, level={}, endDate={}", 
                user.getId(), level.getName(), membership.getEndDate());
                
        } catch (Exception e) {
            logger.error("更新会员信息失败: userId={}", user.getId(), e);
        }
    }
    
    /**
     * 确保订单的会员信息已更新（用于处理订单状态已经是PAID但会员信息未更新的情况）
     * 这个方法不会重复增加积分，只会更新会员等级和到期时间
     */
    public void ensureMembershipUpdated(Long orderId) {
        try {
            Order order = orderRepository.findByIdWithUser(orderId)
                    .orElseThrow(() -> new RuntimeException("订单不存在：" + orderId));
            
            if (order.getUser() == null) {
                logger.warn("ensureMembershipUpdated: 订单没有关联用户, orderId={}", orderId);
                return;
            }
            
            logger.info("ensureMembershipUpdated: 检查并确保会员信息已更新, orderId={}, userId={}", 
                orderId, order.getUser().getId());
            
            // 直接调用更新会员信息的方法
            updateMembershipForOrder(order, order.getUser());
            
        } catch (Exception e) {
            logger.error("ensureMembershipUpdated失败: orderId={}", orderId, e);
        }
    }
    
    /**
     * 取消订单
     */
    public Order cancelOrder(Long orderId, String reason) {
        try {
            Order order = orderRepository.findById(orderId)
                    .orElseThrow(() -> new RuntimeException("订单不存在：" + orderId));
            
            if (!order.canCancel()) {
                throw new RuntimeException("订单当前状态不允许取消");
            }
            
            order.setStatus(OrderStatus.CANCELLED);
            order.setCancelledAt(LocalDateTime.now());
            if (reason != null && !reason.isEmpty()) {
                order.setNotes((order.getNotes() != null ? order.getNotes() + "\n" : "") + 
                    "取消原因：" + reason);
            }
            
            Order cancelledOrder = orderRepository.save(order);
            logger.info("订单取消成功，订单号：{}", order.getOrderNumber());
            
            return cancelledOrder;
            
        } catch (Exception e) {
            logger.error("取消订单失败：", e);
            throw new RuntimeException("取消订单失败：" + e.getMessage());
        }
    }
    
    /**
     * 确认订单支付
     */
    public Order confirmPayment(Long orderId, String paymentId) {
        try {
            Order order = orderRepository.findById(orderId)
                    .orElseThrow(() -> new RuntimeException("订单不存在：" + orderId));
            
            if (!order.canPay()) {
                throw new RuntimeException("订单当前状态不允许支付");
            }
            
            order.setStatus(OrderStatus.PAID);
            order.setPaidAt(LocalDateTime.now());
            
            Order paidOrder = orderRepository.save(order);
            logger.info("订单支付确认成功，订单号：{}，支付ID：{}", 
                order.getOrderNumber(), paymentId);
            
            return paidOrder;
            
        } catch (Exception e) {
            logger.error("确认订单支付失败：", e);
            throw new RuntimeException("确认订单支付失败：" + e.getMessage());
        }
    }
    
    /**
     * 发货
     */
    public Order shipOrder(Long orderId, String trackingNumber) {
        try {
            Order order = orderRepository.findById(orderId)
                    .orElseThrow(() -> new RuntimeException("订单不存在：" + orderId));
            
            if (!order.canShip()) {
                throw new RuntimeException("订单当前状态不允许发货");
            }
            
            order.setStatus(OrderStatus.SHIPPED);
            order.setShippedAt(LocalDateTime.now());
            if (trackingNumber != null && !trackingNumber.isEmpty()) {
                order.setNotes((order.getNotes() != null ? order.getNotes() + "\n" : "") + 
                    "物流单号：" + trackingNumber);
            }
            
            Order shippedOrder = orderRepository.save(order);
            logger.info("订单发货成功，订单号：{}", order.getOrderNumber());
            
            return shippedOrder;
            
        } catch (Exception e) {
            logger.error("订单发货失败：", e);
            throw new RuntimeException("订单发货失败：" + e.getMessage());
        }
    }
    
    /**
     * 完成订单
     */
    public Order completeOrder(Long orderId) {
        try {
            Order order = orderRepository.findById(orderId)
                    .orElseThrow(() -> new RuntimeException("订单不存在：" + orderId));
            
            if (!order.canComplete()) {
                throw new RuntimeException("订单当前状态不允许完成");
            }
            
            order.setStatus(OrderStatus.COMPLETED);
            order.setDeliveredAt(LocalDateTime.now());
            
            Order completedOrder = orderRepository.save(order);
            logger.info("订单完成成功，订单号：{}", order.getOrderNumber());
            
            return completedOrder;
            
        } catch (Exception e) {
            logger.error("完成订单失败：", e);
            throw new RuntimeException("完成订单失败：" + e.getMessage());
        }
    }
    
    /**
     * 统计订单数量
     */
    @Transactional(readOnly = true)
    public long countByUserId(Long userId) {
        return orderRepository.countByUserId(userId);
    }
    
    /**
     * 统计指定状态的订单数量
     */
    @Transactional(readOnly = true)
    public long countByStatus(OrderStatus status) {
        return orderRepository.countByStatus(status);
    }
    
    /**
     * 统计用户指定状态的订单数量
     */
    @Transactional(readOnly = true)
    public long countByUserIdAndStatus(Long userId, OrderStatus status) {
        return orderRepository.countByUserIdAndStatus(userId, status);
    }
    
    /**
     * 查找用户的最近订单
     */
    @Transactional(readOnly = true)
    public List<Order> findRecentOrdersByUserId(Long userId, Pageable pageable) {
        return orderRepository.findRecentOrdersByUserId(userId, pageable);
    }
    
    /**
     * 查找过期的待支付订单
     */
    @Transactional(readOnly = true)
    public List<Order> findExpiredPendingOrders(int expireMinutes) {
        LocalDateTime expireTime = LocalDateTime.now().minusMinutes(expireMinutes);
        return orderRepository.findExpiredPendingOrders(expireTime);
    }
    
    /**
     * 自动取消过期订单
     */
    public int autoCancelExpiredOrders(int expireMinutes) {
        try {
            List<Order> expiredOrders = findExpiredPendingOrders(expireMinutes);
            int cancelledCount = 0;
            
            for (Order order : expiredOrders) {
                try {
                    cancelOrder(order.getId(), "系统自动取消：订单超时未支付");
                    cancelledCount++;
                } catch (Exception e) {
                    logger.warn("自动取消订单失败，订单号：{}", order.getOrderNumber(), e);
                }
            }
            
            logger.info("自动取消过期订单完成，取消数量：{}", cancelledCount);
            return cancelledCount;
            
        } catch (Exception e) {
            logger.error("自动取消过期订单失败：", e);
            return 0;
        }
    }
    
    /**
     * 删除订单（仅管理员可操作）
     */
    public void deleteOrder(Long orderId) {
        try {
            Order order = orderRepository.findById(orderId)
                    .orElseThrow(() -> new RuntimeException("订单不存在：" + orderId));
            
            orderRepository.delete(order);
            logger.info("订单删除成功，订单号：{}", order.getOrderNumber());
            
        } catch (Exception e) {
            logger.error("删除订单失败：", e);
            throw new RuntimeException("删除订单失败：" + e.getMessage());
        }
    }
    
    /**
     * 保存订单
     */
    public Order save(Order order) {
        try {
            Order savedOrder = orderRepository.save(order);
            logger.info("订单保存成功，订单ID：{}", savedOrder.getId());
            return savedOrder;
        } catch (Exception e) {
            logger.error("保存订单失败：", e);
            throw new RuntimeException("保存订单失败：" + e.getMessage());
        }
    }
    
    /**
     * 保存订单项
     */
    public OrderItem saveOrderItem(OrderItem orderItem) {
        try {
            OrderItem savedOrderItem = orderItemRepository.save(orderItem);
            logger.info("订单项保存成功，订单项ID：{}", savedOrderItem.getId());
            return savedOrderItem;
        } catch (Exception e) {
            logger.error("保存订单项失败：", e);
            throw new RuntimeException("保存订单项失败：" + e.getMessage());
        }
    }
    
    /**
     * 分页查找所有订单（支持状态、类型和搜索筛选，预加载User）
     */
    @Transactional(readOnly = true)
    public Page<Order> findAllOrders(Pageable pageable, OrderStatus status, String type, String search) {
        // 基础查询
        Page<Order> result;
        if (status != null && search != null && !search.trim().isEmpty()) {
            result = orderRepository.findByStatusAndOrderNumberContainingIgnoreCaseWithUser(status, search, pageable);
        } else if (status != null) {
            result = orderRepository.findByStatusWithUser(status, pageable);
        } else if (search != null && !search.trim().isEmpty()) {
            result = orderRepository.findByOrderNumberContainingIgnoreCaseWithUser(search, pageable);
        } else {
            result = orderRepository.findAllWithUser(pageable);
        }
        
        // 类型筛选（如果指定了类型）
        // 注意：这种方式在分页时可能导致每页数量不准确，但对于简单场景足够
        // 如需精确分页，需要在 Repository 层添加对应查询方法
        return result;
    }
    
    /**
     * 分页查找用户的订单（支持状态、类型和搜索筛选，预加载User）
     */
    @Transactional(readOnly = true)
    public Page<Order> findOrdersByUser(User user, Pageable pageable, OrderStatus status, String type, String search) {
        if (status != null && search != null && !search.trim().isEmpty()) {
            return orderRepository.findByUserAndStatusAndOrderNumberContainingIgnoreCaseWithUser(user, status, search, pageable);
        } else if (status != null) {
            return orderRepository.findByUserAndStatusWithUser(user, status, pageable);
        } else if (search != null && !search.trim().isEmpty()) {
            return orderRepository.findByUserAndOrderNumberContainingIgnoreCaseWithUser(user, search, pageable);
        } else {
            return orderRepository.findByUserWithUser(user, pageable);
        }
    }
    
    /**
     * 获取所有订单统计
     */
    @Transactional(readOnly = true)
    public Map<String, Object> getOrderStats() {
        Map<String, Object> stats = new HashMap<>();
        
        // 总订单数
        long totalOrders = orderRepository.count();
        stats.put("totalOrders", totalOrders);
        
        // 各状态订单数
        stats.put("pendingOrders", orderRepository.countByStatus(OrderStatus.PENDING));
        stats.put("confirmedOrders", orderRepository.countByStatus(OrderStatus.CONFIRMED));
        stats.put("paidOrders", orderRepository.countByStatus(OrderStatus.PAID));
        stats.put("processingOrders", orderRepository.countByStatus(OrderStatus.PROCESSING));
        stats.put("shippedOrders", orderRepository.countByStatus(OrderStatus.SHIPPED));
        stats.put("deliveredOrders", orderRepository.countByStatus(OrderStatus.DELIVERED));
        stats.put("completedOrders", orderRepository.countByStatus(OrderStatus.COMPLETED));
        stats.put("cancelledOrders", orderRepository.countByStatus(OrderStatus.CANCELLED));
        stats.put("refundedOrders", orderRepository.countByStatus(OrderStatus.REFUNDED));
        
        // 今日订单数
        LocalDateTime today = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0).withNano(0);
        long todayOrders = orderRepository.countByCreatedAtAfter(today);
        stats.put("todayOrders", todayOrders);
        
        // 总金额
        BigDecimal totalAmount = orderRepository.sumTotalAmountByStatus(OrderStatus.COMPLETED);
        stats.put("totalAmount", totalAmount != null ? totalAmount : BigDecimal.ZERO);
        
        return stats;
    }
    
    /**
     * 批量删除订单
     */
    public int deleteOrdersByIds(List<Long> orderIds) {
        try {
            int deletedCount = 0;
            
            for (Long orderId : orderIds) {
                try {
                    Order order = orderRepository.findById(orderId)
                            .orElseThrow(() -> new RuntimeException("订单不存在：" + orderId));
                    
                    // 只有已取消或已退款的订单才能删除
                    if (order.getStatus() == OrderStatus.CANCELLED || order.getStatus() == OrderStatus.REFUNDED) {
                        orderRepository.delete(order);
                        deletedCount++;
                        logger.info("订单删除成功，订单号：{}", order.getOrderNumber());
                    } else {
                        logger.warn("订单状态不允许删除，订单号：{}，状态：{}", order.getOrderNumber(), order.getStatus());
                    }
                } catch (Exception e) {
                    logger.warn("删除订单失败，订单ID：{}", orderId, e);
                }
            }
            
            logger.info("批量删除订单完成，成功删除：{}，总数：{}", deletedCount, orderIds.size());
            return deletedCount;
            
        } catch (Exception e) {
            logger.error("批量删除订单失败：", e);
            throw new RuntimeException("批量删除订单失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取用户订单统计
     */
    @Transactional(readOnly = true)
    public Map<String, Object> getOrderStatsByUser(User user) {
        Map<String, Object> stats = new HashMap<>();
        
        // 用户总订单数
        long totalOrders = orderRepository.countByUser(user);
        stats.put("totalOrders", totalOrders);
        
        // 用户各状态订单数
        stats.put("pendingOrders", orderRepository.countByUserAndStatus(user, OrderStatus.PENDING));
        stats.put("confirmedOrders", orderRepository.countByUserAndStatus(user, OrderStatus.CONFIRMED));
        stats.put("paidOrders", orderRepository.countByUserAndStatus(user, OrderStatus.PAID));
        stats.put("processingOrders", orderRepository.countByUserAndStatus(user, OrderStatus.PROCESSING));
        stats.put("shippedOrders", orderRepository.countByUserAndStatus(user, OrderStatus.SHIPPED));
        stats.put("deliveredOrders", orderRepository.countByUserAndStatus(user, OrderStatus.DELIVERED));
        stats.put("completedOrders", orderRepository.countByUserAndStatus(user, OrderStatus.COMPLETED));
        stats.put("cancelledOrders", orderRepository.countByUserAndStatus(user, OrderStatus.CANCELLED));
        stats.put("refundedOrders", orderRepository.countByUserAndStatus(user, OrderStatus.REFUNDED));
        
        // 用户今日订单数
        LocalDateTime today = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0).withNano(0);
        long todayOrders = orderRepository.countByUserAndCreatedAtAfter(user, today);
        stats.put("todayOrders", todayOrders);
        
        // 用户总金额
        BigDecimal totalAmount = orderRepository.sumTotalAmountByUserAndStatus(user, OrderStatus.COMPLETED);
        stats.put("totalAmount", totalAmount != null ? totalAmount : BigDecimal.ZERO);
        
        return stats;
    }
    
    /**
     * 自动取消超时未支付的订单
     * 超过30分钟未支付的PENDING订单自动取消
     */
    public int autoCancelTimeoutOrders() {
        try {
            // 计算30分钟前的时间
            LocalDateTime cancelTime = LocalDateTime.now().minusMinutes(30);
            
            // 查找需要自动取消的订单（状态为PENDING且创建时间超过30分钟）
            List<Order> timeoutOrders = orderRepository.findByStatusAndCreatedAtBefore(OrderStatus.PENDING, cancelTime);
            
            if (timeoutOrders.isEmpty()) {
                return 0;
            }
            
            int cancelledCount = 0;
            for (Order order : timeoutOrders) {
                try {
                    order.setStatus(OrderStatus.CANCELLED);
                    order.setCancelledAt(LocalDateTime.now());
                    order.setNotes((order.getNotes() != null ? order.getNotes() + "\n" : "") + 
                        "系统自动取消：订单超时30分钟未支付");
                    orderRepository.save(order);
                    cancelledCount++;
                    logger.info("订单自动取消成功，订单号：{}", order.getOrderNumber());
                } catch (Exception e) {
                    logger.error("自动取消订单失败，订单号：{}", order.getOrderNumber(), e);
                }
            }
            
            if (cancelledCount > 0) {
                logger.info("本次共自动取消 {} 个超时订单", cancelledCount);
            }
            
            return cancelledCount;
            
        } catch (Exception e) {
            logger.error("自动取消超时订单任务执行失败", e);
            return 0;
        }
    }
}
