package org.xyzh.crontab.scheduler;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import org.xyzh.common.dto.crontab.TbCrontabTask;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;

/**
 * @description 定时任务调度管理器
 * @filename SchedulerManager.java
 * @author yslg
 * @copyright xyzh
 * @since 2025-10-25
 */
@Component
public class SchedulerManager {

    private static final Logger logger = LoggerFactory.getLogger(SchedulerManager.class);

    @Autowired
    private TaskScheduler taskScheduler;

    @Autowired
    @Qualifier("crontabTaskExecutor")
    private TaskExecutor taskExecutor;

    /**
     * 存储已调度的任务
     * Key: 任务ID, Value: ScheduledFuture
     */
    private final Map<String, ScheduledFuture<?>> scheduledTasks = new ConcurrentHashMap<>();

    /**
     * @description 调度任务
     * @param task 任务对象
     * @author yslg
     * @since 2025-10-25
     */
    public void scheduleTask(TbCrontabTask task) {
        try {
            String taskId = task.getID();
            
            // 如果任务已经在调度中，先取消
            if (scheduledTasks.containsKey(taskId)) {
                unscheduleTask(task);
            }

            // 创建Cron触发器
            CronTrigger cronTrigger = new CronTrigger(task.getCronExpression());

            // 调度任务
            ScheduledFuture<?> future = taskScheduler.schedule(
                () -> taskExecutor.executeTask(task),
                cronTrigger
            );

            // 保存调度信息
            scheduledTasks.put(taskId, future);
            
            logger.info("任务调度成功: {} [{}]", task.getTaskName(), task.getCronExpression());
        } catch (Exception e) {
            logger.error("任务调度失败: {}", task.getTaskName(), e);
        }
    }

    /**
     * @description 取消任务调度
     * @param task 任务对象
     * @author yslg
     * @since 2025-10-25
     */
    public void unscheduleTask(TbCrontabTask task) {
        try {
            String taskId = task.getID();
            ScheduledFuture<?> future = scheduledTasks.get(taskId);
            
            if (future != null) {
                future.cancel(false);
                scheduledTasks.remove(taskId);
                logger.info("任务取消调度成功: {}", task.getTaskName());
            }
        } catch (Exception e) {
            logger.error("任务取消调度失败: {}", task.getTaskName(), e);
        }
    }

    /**
     * @description 重新调度任务
     * @param task 任务对象
     * @author yslg
     * @since 2025-10-25
     */
    public void rescheduleTask(TbCrontabTask task) {
        unscheduleTask(task);
        scheduleTask(task);
    }

    /**
     * @description 立即执行一次任务
     * @param task 任务对象
     * @author yslg
     * @since 2025-10-25
     */
    public void executeTaskOnce(TbCrontabTask task) {
        try {
            taskExecutor.executeTask(task);
            logger.info("立即执行任务: {}", task.getTaskName());
        } catch (Exception e) {
            logger.error("立即执行任务失败: {}", task.getTaskName(), e);
        }
    }

    /**
     * @description 检查任务是否在调度中
     * @param taskId 任务ID
     * @return boolean
     * @author yslg
     * @since 2025-10-25
     */
    public boolean isTaskScheduled(String taskId) {
        return scheduledTasks.containsKey(taskId);
    }

    /**
     * @description 获取所有调度中的任务数量
     * @return int
     * @author yslg
     * @since 2025-10-25
     */
    public int getScheduledTaskCount() {
        return scheduledTasks.size();
    }

    /**
     * @description 清除所有任务调度
     * @author yslg
     * @since 2025-10-25
     */
    public void clearAllSchedules() {
        scheduledTasks.forEach((taskId, future) -> {
            future.cancel(false);
        });
        scheduledTasks.clear();
        logger.info("已清除所有任务调度");
    }
}

