package cn.gov.customs.wxjy.task;

import cn.gov.customs.wxjy.constants.TaskStatusEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 定时任务管理类
 * 负责调度和执行所有定时任务
 */
@Component
@Slf4j
public class ScheduledTasks {

    // 任务执行线程池
    private ExecutorService taskExecutor;

    // 任务映射表
    private final Map<String, BaseBusinessTask<?>> taskMap = new ConcurrentHashMap<>();

    @Autowired(required = false)
    private PackCatalogTask packCatalogTask;

    @Autowired(required = false)
    private GoodsCatalogTask goodsCatalogTask;

    @Autowired(required = false)
    private ChemicalsCatalogTask chemicalsCatalogTask;

    /**
     * 初始化方法
     */
    @PostConstruct
    public void init() {
        // 创建任务执行线程池
        taskExecutor = Executors.newFixedThreadPool(5, new TaskThreadFactory());

        // 注册任务
        registerTasks();

        log.info("定时任务管理器初始化完成，已注册{}个任务", taskMap.size());
    }

    /**
     * 注册所有任务
     */
    private void registerTasks() {
        if (packCatalogTask != null) {
            taskMap.put(packCatalogTask.getTaskCode(), packCatalogTask);
            log.info("注册任务：{}", packCatalogTask.getTaskName());
        }

        if (goodsCatalogTask != null) {
            taskMap.put(goodsCatalogTask.getTaskCode(), goodsCatalogTask);
            log.info("注册任务：{}", goodsCatalogTask.getTaskName());
        }

        if (chemicalsCatalogTask != null) {
            taskMap.put(chemicalsCatalogTask.getTaskCode(), chemicalsCatalogTask);
            log.info("注册任务：{}", chemicalsCatalogTask.getTaskName());
        }
    }

    /**
     * 包装种类定时任务调度
     */
    @Scheduled(cron = "0 10 3 ? * SAT")
    public void schedulePackCatalogTask() {
        executeTask(packCatalogTask, "包装种类目录推送数据");
    }

    /**
     * 危险货物定时任务调度
     */
    @Scheduled(cron = "0 20 3 ? * SAT")
    public void scheduleGoodsCatalogTask() {
        executeTask(goodsCatalogTask, "危险货物目录推送数据");
    }

    /**
     * 危化品目录定时任务调度
     */
    @Scheduled(cron = "0 30 3 ? * SAT")
    public void scheduleChemicalsCatalogTask() {
        executeTask(chemicalsCatalogTask, "危化品目录推送数据");
    }

    /**
     * 执行任务
     */
    private void executeTask(BaseBusinessTask<?> task, String taskDescription) {
        if (task == null) {
            log.warn("任务未配置: {}", taskDescription);
            return;
        }

        String taskName = task.getTaskName();
        log.info("{}定时任务开始执行", taskName);

        // 提交任务到线程池执行
        taskExecutor.submit(() -> {
            long startTime = System.currentTimeMillis();
            try {
                // 执行任务
                task.execute();
                log.info("{}定时任务执行完成，耗时：{}ms",
                        taskName, System.currentTimeMillis() - startTime);
            } catch (Exception e) {
                log.error("{}定时任务执行异常，业务类型：{}",
                        taskName, task.getTaskCode(), e);
            }
        });
    }

    /**
     * 任务线程工厂
     */
    private static class TaskThreadFactory implements ThreadFactory {
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        private final String namePrefix = "task-thread-";

        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r, namePrefix + threadNumber.getAndIncrement());
            t.setDaemon(true);
            t.setPriority(Thread.NORM_PRIORITY);
            return t;
        }
    }
}