package com.ruoyi.dj.mqtt.service;

import com.ruoyi.dj.controller.FlightController;
import com.ruoyi.dj.controller.NewTaskController;
import com.ruoyi.dj.mqtt.dto.FlightTaskDto;
import com.ruoyi.dj.mqtt.dto.FlightTaskExecuteDto;
import com.ruoyi.system.domain.Missions;
import com.ruoyi.system.domain.ScheduleTask;
import com.ruoyi.system.domain.VideoInfo;
import com.ruoyi.system.service.IMissionsService;
import com.ruoyi.system.service.IScheduleTaskService;
import com.ruoyi.system.service.IVideoInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;

@Slf4j
@Service
public class TaskSchedulingService {
    private ConcurrentHashMap<Long, ScheduledFuture<?>> jobsMap = new ConcurrentHashMap<>();

    @Autowired
    private TaskScheduler taskScheduler;

    @Autowired
    private IScheduleTaskService scheduleTaskService;

    @Resource
    private IVideoInfoService videoInfoService;

    @Resource
    private FlightController flightController;
    @Resource
    private IMissionsService missionsService;
    @Resource
    private NewTaskController newTaskController;

    public void scheduleUpdateTasks() {
        taskScheduler.scheduleAtFixedRate(this::updateNewTasks, 1000 * 30);  // 每10秒执行一次更新任务
    }

    private void updateNewTasks() {
        log.info("更新前的定时任务总数: {}", jobsMap.size());
        Missions missions = new Missions();
        missions.setType(1L);
        List<Missions> missionsList = missionsService.selectMissionsList(missions);
        log.info("取消所有现有任务。");
        jobsMap.forEach((id, future) -> future.cancel(false));
        jobsMap.clear();
        log.info("根据最新的数据库条目添加新任务。");
        missionsList.forEach(task -> addTaskToScheduler(task.getId(), task));
        log.info("更新后的定时任务总数: {}", jobsMap.size());
    }


    public void addTaskToScheduler(Long taskId, Missions task) {
        ScheduledFuture<?> scheduledTask = taskScheduler.schedule(() -> runTask(task), new CronTrigger(buildCronExpression(task)));
        jobsMap.put(taskId, scheduledTask);
        log.info("已添加任务: {}, 当前任务总数: {}", taskId, jobsMap.size());
    }


    private String buildCronExpression(Missions task) {
        String timer = task.getTimer();  // 获取时间字符串

        // 定义时间格式，假设输入格式为 "yyyy-MM-dd HH:mm:ss"
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date parsedDate;

        try {
            // 解析时间字符串为 Date 对象
            parsedDate = dateFormat.parse(timer);
        } catch (ParseException e) {
            log.error("时间解析错误: {}", timer, e);
            return null;  // 或者抛出异常，取决于你的业务逻辑
        }

        // 使用 Calendar 来从 Date 中提取时间字段
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(parsedDate);

        int second = calendar.get(Calendar.SECOND);
        int minute = calendar.get(Calendar.MINUTE);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        int month = calendar.get(Calendar.MONTH) + 1;  // Calendar.MONTH 返回值从0开始，所以+1
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1; // Cron 表达式中的星期, 0=周日

        // 构建 Cron 表达式
        String cronExpression = String.format("%d %d %d %d %d ?",
                second,  // 秒
                minute,  // 分
                hour,    // 时
                day,     // 日
                month    // 月
        );

        log.info("构建的 Cron 表达式: {}", cronExpression);
        return cronExpression;
    }

    private void runTask(Missions task) {
        log.info("尝试执行任务: {}", task.getId());
        try {
//            // TODO 下发定时
            task.setTimeStamp(System.currentTimeMillis());
            task.setType(1L);
            Map<String, String> map = newTaskController.flightTaskPrepare(task);
            String flightId = map.get("flightId");
            String taskId = map.get("taskId");
//
//            // TODO 执行任务
            FlightTaskExecuteDto flightTaskExecuteDto = new FlightTaskExecuteDto();
            flightTaskExecuteDto.setFlightId(flightId);
            flightTaskExecuteDto.setGateway(task.getGateway());
            flightTaskExecuteDto.setTaskId(Long.valueOf(taskId));
//
//            // 执行定时
            newTaskController.executeTask(flightTaskExecuteDto);
            log.info("定时飞行任务已执行: {}", task.getId());
        } catch (Exception e) {
            log.error("执行任务时出错: {}", task.getId(), e);
        }
    }
}
