package com.ruoyi.notification.service.impl;

import java.util.Date;
import java.util.List;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.notification.domain.ScheduledTask;
import com.ruoyi.notification.mapper.ScheduledTaskMapper;
import com.ruoyi.notification.service.IScheduledTaskService;
import com.ruoyi.notification.task.DigitalCreditTask;

/**
 * 定时任务Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-12-19
 */
@Service
public class ScheduledTaskServiceImpl implements IScheduledTaskService 
{
    private static final Logger log = LoggerFactory.getLogger(ScheduledTaskServiceImpl.class);

    @Autowired
    private ScheduledTaskMapper scheduledTaskMapper;

    @Autowired
    private Scheduler scheduler;

    /**
     * 查询定时任务
     * 
     * @param taskId 定时任务主键
     * @return 定时任务
     */
    @Override
    public ScheduledTask selectScheduledTaskByTaskId(Long taskId)
    {
        return scheduledTaskMapper.selectScheduledTaskByTaskId(taskId);
    }

    /**
     * 查询定时任务列表
     * 
     * @param scheduledTask 定时任务
     * @return 定时任务
     */
    @Override
    public List<ScheduledTask> selectScheduledTaskList(ScheduledTask scheduledTask)
    {
        return scheduledTaskMapper.selectScheduledTaskList(scheduledTask);
    }

    /**
     * 新增定时任务
     * 
     * @param scheduledTask 定时任务
     * @return 结果
     */
    @Override
    public int insertScheduledTask(ScheduledTask scheduledTask)
    {
        scheduledTask.setCreateTime(DateUtils.getNowDate());
        scheduledTask.setUpdateTime(DateUtils.getNowDate());
        scheduledTask.setExecuteCount(0L);
        scheduledTask.setFailureCount(0L);
        if (scheduledTask.getMaxRetryCount() == null) {
            scheduledTask.setMaxRetryCount(3L);
        }
        if (scheduledTask.getEnabled() == null) {
            scheduledTask.setEnabled("1");
        }
        if (scheduledTask.getTaskStatus() == null) {
            scheduledTask.setTaskStatus("ACTIVE");
        }
        
        int result = scheduledTaskMapper.insertScheduledTask(scheduledTask);
        
        // 如果任务启用，则添加到调度器
        if ("1".equals(scheduledTask.getEnabled()) && "ACTIVE".equals(scheduledTask.getTaskStatus())) {
            try {
                addJobToScheduler(scheduledTask);
            } catch (SchedulerException e) {
                log.error("添加定时任务到调度器失败: {}", e.getMessage());
            }
        }
        
        return result;
    }

    /**
     * 修改定时任务
     * 
     * @param scheduledTask 定时任务
     * @return 结果
     */
    @Override
    public int updateScheduledTask(ScheduledTask scheduledTask)
    {
        scheduledTask.setUpdateTime(DateUtils.getNowDate());
        
        // 先从调度器中移除旧任务
        try {
            removeJobFromScheduler(scheduledTask.getTaskId());
        } catch (SchedulerException e) {
            log.error("从调度器移除任务失败: {}", e.getMessage());
        }
        
        int result = scheduledTaskMapper.updateScheduledTask(scheduledTask);
        
        // 如果任务启用，则重新添加到调度器
        if ("1".equals(scheduledTask.getEnabled()) && "ACTIVE".equals(scheduledTask.getTaskStatus())) {
            try {
                addJobToScheduler(scheduledTask);
            } catch (SchedulerException e) {
                log.error("重新添加定时任务到调度器失败: {}", e.getMessage());
            }
        }
        
        return result;
    }

    /**
     * 批量删除定时任务
     * 
     * @param taskIds 需要删除的定时任务主键集合
     * @return 结果
     */
    @Override
    public int deleteScheduledTaskByTaskIds(Long[] taskIds)
    {
        // 先从调度器中移除任务
        for (Long taskId : taskIds) {
            try {
                removeJobFromScheduler(taskId);
            } catch (SchedulerException e) {
                log.error("从调度器移除任务失败: {}", e.getMessage());
            }
        }
        
        return scheduledTaskMapper.deleteScheduledTaskByTaskIds(taskIds);
    }

    /**
     * 删除定时任务信息
     * 
     * @param taskId 定时任务主键
     * @return 结果
     */
    @Override
    public int deleteScheduledTaskByTaskId(Long taskId)
    {
        // 先从调度器中移除任务
        try {
            removeJobFromScheduler(taskId);
        } catch (SchedulerException e) {
            log.error("从调度器移除任务失败: {}", e.getMessage());
        }
        
        return scheduledTaskMapper.deleteScheduledTaskByTaskId(taskId);
    }

    /**
     * 启动定时任务
     */
    @Override
    public boolean startTask(Long taskId) {
        try {
            ScheduledTask task = scheduledTaskMapper.selectScheduledTaskByTaskId(taskId);
            if (task != null) {
                task.setTaskStatus("ACTIVE");
                task.setEnabled("1");
                updateScheduledTask(task);
                return true;
            }
        } catch (Exception e) {
            log.error("启动定时任务失败: {}", e.getMessage());
        }
        return false;
    }

    /**
     * 停止定时任务
     */
    @Override
    public boolean stopTask(Long taskId) {
        try {
            ScheduledTask task = scheduledTaskMapper.selectScheduledTaskByTaskId(taskId);
            if (task != null) {
                task.setTaskStatus("STOPPED");
                task.setEnabled("0");
                updateScheduledTask(task);
                return true;
            }
        } catch (Exception e) {
            log.error("停止定时任务失败: {}", e.getMessage());
        }
        return false;
    }

    /**
     * 暂停定时任务
     */
    @Override
    public boolean pauseTask(Long taskId) {
        try {
            JobKey jobKey = JobKey.jobKey("task_" + taskId, "DEFAULT");
            scheduler.pauseJob(jobKey);
            
            ScheduledTask task = scheduledTaskMapper.selectScheduledTaskByTaskId(taskId);
            if (task != null) {
                task.setTaskStatus("PAUSED");
                scheduledTaskMapper.updateScheduledTask(task);
            }
            return true;
        } catch (SchedulerException e) {
            log.error("暂停定时任务失败: {}", e.getMessage());
        }
        return false;
    }

    /**
     * 恢复定时任务
     */
    @Override
    public boolean resumeTask(Long taskId) {
        try {
            JobKey jobKey = JobKey.jobKey("task_" + taskId, "DEFAULT");
            scheduler.resumeJob(jobKey);
            
            ScheduledTask task = scheduledTaskMapper.selectScheduledTaskByTaskId(taskId);
            if (task != null) {
                task.setTaskStatus("ACTIVE");
                scheduledTaskMapper.updateScheduledTask(task);
            }
            return true;
        } catch (SchedulerException e) {
            log.error("恢复定时任务失败: {}", e.getMessage());
        }
        return false;
    }

    /**
     * 立即执行定时任务
     */
    @Override
    public boolean runTaskNow(Long taskId) {
        try {
            JobKey jobKey = JobKey.jobKey("task_" + taskId, "DEFAULT");
            scheduler.triggerJob(jobKey);
            return true;
        } catch (SchedulerException e) {
            log.error("立即执行定时任务失败: {}", e.getMessage());
        }
        return false;
    }

    /**
     * 初始化定时任务
     */
    @Override
    public void initScheduledTasks() {
        log.info("开始初始化定时任务...");
        
        List<ScheduledTask> enabledTasks = scheduledTaskMapper.selectEnabledScheduledTasks();
        for (ScheduledTask task : enabledTasks) {
            try {
                addJobToScheduler(task);
                log.info("初始化定时任务成功: {}", task.getTaskName());
            } catch (SchedulerException e) {
                log.error("初始化定时任务失败: {}, 错误: {}", task.getTaskName(), e.getMessage());
            }
        }
        
        log.info("定时任务初始化完成，共初始化 {} 个任务", enabledTasks.size());
    }

    /**
     * 创建合同到期提醒任务
     */
    @Override
    public boolean createContractExpiryReminderTask(Long contractId, int reminderDays) {
        try {
            ScheduledTask task = new ScheduledTask();
            task.setTaskName("合同到期提醒_" + contractId);
            task.setTaskType("CONTRACT_EXPIRY_REMINDER");
            task.setTaskStatus("ACTIVE");
            task.setCronExpression("0 0 9 * * ?"); // 每天上午9点执行
            task.setTargetObject("digitalCreditTask");
            task.setTargetMethod("checkContractExpiry");
            task.setMethodParams(contractId + "," + reminderDays);
            task.setDescription("合同ID " + contractId + " 的到期提醒任务，提前 " + reminderDays + " 天提醒");
            task.setEnabled("1");
            task.setMaxRetryCount(3L);
            
            return insertScheduledTask(task) > 0;
        } catch (Exception e) {
            log.error("创建合同到期提醒任务失败: {}", e.getMessage());
            return false;
        }
    }

    /**
     * 创建合同状态检查任务
     */
    @Override
    public boolean createContractStatusCheckTask() {
        try {
            ScheduledTask task = new ScheduledTask();
            task.setTaskName("合同状态检查任务");
            task.setTaskType("CONTRACT_STATUS_CHECK");
            task.setTaskStatus("ACTIVE");
            task.setCronExpression("0 0 */2 * * ?"); // 每2小时执行一次
            task.setTargetObject("digitalCreditTask");
            task.setTargetMethod("checkContractStatus");
            task.setMethodParams("");
            task.setDescription("定期检查合同状态，处理状态变更和异常情况");
            task.setEnabled("1");
            task.setMaxRetryCount(3L);
            
            return insertScheduledTask(task) > 0;
        } catch (Exception e) {
            log.error("创建合同状态检查任务失败: {}", e.getMessage());
            return false;
        }
    }

    /**
     * 更新任务执行统计
     */
    @Override
    public void updateTaskExecutionStats(Long taskId, boolean success) {
        try {
            scheduledTaskMapper.updateTaskExecutionStats(taskId, success);
        } catch (Exception e) {
            log.error("更新任务执行统计失败: {}", e.getMessage());
        }
    }

    /**
     * 添加任务到调度器
     */
    private void addJobToScheduler(ScheduledTask task) throws SchedulerException {
        JobDetail jobDetail = JobBuilder.newJob(DigitalCreditTask.class)
                .withIdentity("task_" + task.getTaskId(), "DEFAULT")
                .usingJobData("taskId", task.getTaskId())
                .usingJobData("targetObject", task.getTargetObject())
                .usingJobData("targetMethod", task.getTargetMethod())
                .usingJobData("methodParams", task.getMethodParams() != null ? task.getMethodParams() : "")
                .build();

        CronTrigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("trigger_" + task.getTaskId(), "DEFAULT")
                .withSchedule(CronScheduleBuilder.cronSchedule(task.getCronExpression()))
                .build();

        scheduler.scheduleJob(jobDetail, trigger);
        
        // 更新下次执行时间
        Date nextFireTime = trigger.getNextFireTime();
        if (nextFireTime != null) {
            scheduledTaskMapper.updateNextExecuteTime(task.getTaskId(), nextFireTime);
        }
    }

    /**
     * 从调度器移除任务
     */
    private void removeJobFromScheduler(Long taskId) throws SchedulerException {
        JobKey jobKey = JobKey.jobKey("task_" + taskId, "DEFAULT");
        if (scheduler.checkExists(jobKey)) {
            scheduler.deleteJob(jobKey);
        }
    }
}