package com.gxwebsoft.shop.task;

import com.gxwebsoft.common.core.annotation.IgnoreTenant;
import com.gxwebsoft.shop.config.OrderConfigProperties;
import com.gxwebsoft.shop.entity.ShopOrder;
import com.gxwebsoft.shop.service.OrderCancelService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 订单自动取消定时任务
 *
 * @author WebSoft
 * @since 2025-01-26
 */
@Slf4j
@Component
@ConditionalOnProperty(prefix = "shop.order.auto-cancel", name = "enabled", havingValue = "true", matchIfMissing = true)
public class OrderAutoCancelTask {

    @Autowired
    private OrderCancelService orderCancelService;

    @Autowired
    private OrderConfigProperties orderConfig;

    @Value("${spring.profiles.active:dev}")
    private String activeProfile;

    /**
     * 自动取消超时订单
     * 生产环境：每5分钟执行一次
     * 开发环境：每1分钟执行一次（便于测试）
     */
    @Scheduled(cron = "${shop.order.auto-cancel.cron:0 */5 * * * ?}")
    @IgnoreTenant("定时任务需要处理所有租户的超时订单")
    public void cancelExpiredOrders() {
        if (!orderConfig.getAutoCancel().isEnabled()) {
            log.debug("订单自动取消功能已禁用");
            return;
        }

        log.info("开始执行订单自动取消任务...");

        try {
            long startTime = System.currentTimeMillis();
            int totalCancelledCount = 0;

            // 处理默认配置的订单
            int defaultCancelledCount = processDefaultTimeoutOrders();
            totalCancelledCount += defaultCancelledCount;

            // 处理租户特殊配置的订单
            int tenantCancelledCount = processTenantSpecificOrders();
            totalCancelledCount += tenantCancelledCount;

            long endTime = System.currentTimeMillis();
            long duration = endTime - startTime;

            log.info("订单自动取消任务完成，总取消数量: {}，默认配置: {}，租户配置: {}，耗时: {}ms",
                    totalCancelledCount, defaultCancelledCount, tenantCancelledCount, duration);

            // 开发环境输出更详细的日志
            if ("dev".equals(activeProfile)) {
                log.debug("开发环境 - 订单自动取消详情: 总共取消{}个订单", totalCancelledCount);
            }

        } catch (Exception e) {
            log.error("订单自动取消任务执行失败", e);
        }
    }

    /**
     * 处理使用默认超时配置的订单
     */
    private int processDefaultTimeoutOrders() {
        try {
            Integer defaultTimeout = orderConfig.getAutoCancel().getDefaultTimeoutMinutes();
            Integer batchSize = orderConfig.getAutoCancel().getBatchSize();

            log.debug("处理默认超时订单，超时时间: {}分钟，批量大小: {}", defaultTimeout, batchSize);

            List<ShopOrder> expiredOrders = orderCancelService.findExpiredUnpaidOrders(defaultTimeout, batchSize);

            if (expiredOrders.isEmpty()) {
                log.debug("没有找到使用默认配置的超时订单");
                return 0;
            }

            // 过滤掉有特殊租户配置的订单
            List<ShopOrder> ordersToCancel = filterOrdersWithoutTenantConfig(expiredOrders);

            if (ordersToCancel.isEmpty()) {
                log.debug("过滤后没有需要使用默认配置取消的订单");
                return 0;
            }

            int cancelledCount = orderCancelService.batchCancelOrders(ordersToCancel);
            log.info("默认配置取消订单完成，找到: {}个，过滤后: {}个，成功取消: {}个",
                    expiredOrders.size(), ordersToCancel.size(), cancelledCount);

            return cancelledCount;

        } catch (Exception e) {
            log.error("处理默认超时订单失败", e);
            return 0;
        }
    }

    /**
     * 处理租户特殊配置的订单
     */
    private int processTenantSpecificOrders() {
        try {
            List<OrderConfigProperties.TenantCancelConfig> tenantConfigs = orderConfig.getAutoCancel().getTenantConfigs();
            if (tenantConfigs == null || tenantConfigs.isEmpty()) {
                log.debug("没有配置租户特殊超时规则");
                return 0;
            }

            int totalCancelledCount = 0;
            Integer batchSize = orderConfig.getAutoCancel().getBatchSize();

            for (OrderConfigProperties.TenantCancelConfig tenantConfig : tenantConfigs) {
                if (!tenantConfig.isEnabled()) {
                    log.debug("租户{}的自动取消功能已禁用", tenantConfig.getTenantId());
                    continue;
                }

                log.debug("处理租户{}的超时订单，超时时间: {}分钟",
                        tenantConfig.getTenantId(), tenantConfig.getTimeoutMinutes());

                List<ShopOrder> tenantExpiredOrders = orderCancelService.findExpiredUnpaidOrdersByTenant(
                        tenantConfig.getTenantId(), tenantConfig.getTimeoutMinutes(), batchSize);

                if (!tenantExpiredOrders.isEmpty()) {
                    int cancelledCount = orderCancelService.batchCancelOrders(tenantExpiredOrders);
                    totalCancelledCount += cancelledCount;

                    log.info("租户{}取消订单完成，找到: {}个，成功取消: {}个",
                            tenantConfig.getTenantId(), tenantExpiredOrders.size(), cancelledCount);
                }
            }

            return totalCancelledCount;

        } catch (Exception e) {
            log.error("处理租户特殊配置订单失败", e);
            return 0;
        }
    }

    /**
     * 过滤掉有租户特殊配置的订单
     */
    private List<ShopOrder> filterOrdersWithoutTenantConfig(List<ShopOrder> orders) {
        List<OrderConfigProperties.TenantCancelConfig> tenantConfigs = orderConfig.getAutoCancel().getTenantConfigs();
        if (tenantConfigs == null || tenantConfigs.isEmpty()) {
            return orders;
        }

        return orders.stream()
                .filter(order -> {
                    // 检查该订单的租户是否有特殊配置
                    return tenantConfigs.stream()
                            .noneMatch(config -> config.isEnabled() && config.getTenantId().equals(order.getTenantId()));
                })
                .collect(java.util.stream.Collectors.toList());
    }

    /**
     * 手动触发订单自动取消任务（用于测试）
     */
    @IgnoreTenant("手动触发的定时任务需要处理所有租户的超时订单")
    public void manualCancelExpiredOrders() {
        log.info("手动触发订单自动取消任务...");
        cancelExpiredOrders();
    }

    /**
     * 获取任务状态信息
     */
    public String getTaskStatus() {
        return String.format("订单自动取消任务状态 - 启用: %s, 默认超时: %d分钟, 检查间隔: %d分钟, 批量大小: %d",
                orderConfig.getAutoCancel().isEnabled(),
                orderConfig.getAutoCancel().getDefaultTimeoutMinutes(),
                orderConfig.getAutoCancel().getCheckIntervalMinutes(),
                orderConfig.getAutoCancel().getBatchSize());
    }
}
