package com.xvji.quartz;

import com.xvji.domain.PredictTask;
import com.xvji.domain.TrainTask;
import com.xvji.service.PredictTaskService;
import com.xvji.service.TrainTaskService;
import com.xvji.service.task.TaskComponentExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.quartz.DisallowConcurrentExecution;
// 实现ApplicationContextAware，获取Spring上下文
//阻止同一个任务并发执行
//@DisallowConcurrentExecution
@Component
public class TaskQuartzJob implements ApplicationContextAware {

    private static final Logger log = LoggerFactory.getLogger(TaskQuartzJob.class);
    private static ApplicationContext applicationContext; // 静态Spring上下文

    // 实现接口方法，保存Spring上下文
    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        TaskQuartzJob.applicationContext = context;
    }

    /**
     * 手动获取Bean
     */
    private <T> T getBean(Class<T> clazz) {
        return applicationContext.getBean(clazz);
    }

    /**
     * 预测任务执行入口：通过是否抛异常判断成功/失败
     */
    public void executePredictTask(Integer taskId) {
        // 记录开始时间，用于计算执行耗时
        long startTime = System.currentTimeMillis();

        try {
            // 获取TaskComponentExecutor
            TaskComponentExecutor componentExecutor = getBean(TaskComponentExecutor.class);
            componentExecutor.executeComponents(taskId.longValue(), 1);

            // 未抛异常视为成功
            PredictTaskService predictTaskService = getBean(PredictTaskService.class);
            PredictTask predictTask = new PredictTask();
            predictTask.setPTaskId(taskId.longValue());
            //predictTask.setPTaskStatus(1); // 1-成功
            // 记录成功信息和耗时
            long costTime = System.currentTimeMillis() - startTime;
            predictTask.setPRunInfo("执行成功，耗时：" + costTime + "ms");

            predictTaskService.updateById(predictTask);
            log.info("预测任务[ID:{}]执行成功，状态更新为1，耗时：{}ms", taskId, costTime);

        } catch (Exception e) {
            // 若抛异常，视为失败，记录异常信息
            PredictTaskService predictTaskService = getBean(PredictTaskService.class);
            PredictTask predictTask = new PredictTask();
            predictTask.setPTaskId(taskId.longValue());
            //predictTask.setPTaskStatus(0); // 0-失败
            // 记录失败原因和异常信息
            long costTime = System.currentTimeMillis() - startTime;
            predictTask.setPRunInfo("执行失败（耗时：" + costTime + "ms）：" + e.getMessage());

            predictTaskService.updateById(predictTask);
            log.error("预测任务[ID:{}]执行失败，状态更新为0", taskId, e);
            throw new RuntimeException("预测任务定时执行失败：" + e.getMessage(), e);
        }
    }

    /**
     * 训练任务执行入口：同理适配void返回值
     */
    public void executeTrainTask(Integer taskId) {
        long startTime = System.currentTimeMillis();
        String analysisReport = null;

        try {
            TaskComponentExecutor componentExecutor = getBean(TaskComponentExecutor.class);
            // 执行void方法
            componentExecutor.executeComponents(taskId.longValue(), 0);

            // 获取分析报告组件的返回结果
            analysisReport = componentExecutor.getAnalysisReportResult();

            // 无异常  成功
            TrainTaskService trainTaskService = getBean(TrainTaskService.class);
            TrainTask trainTask = new TrainTask();
            trainTask.setTTaskId(taskId.longValue());
            //trainTask.setTTaskStatus(1); // 1-成功
            long costTime = System.currentTimeMillis() - startTime;
            trainTask.setTRunInfo("执行成功，耗时：" + costTime + "ms");

            // 将分析报告结果写入train_task表
            if (analysisReport != null && !analysisReport.isEmpty()) {
                trainTask.setTAnalysisReport(analysisReport);
            }

            trainTaskService.updateById(trainTask);
            log.info("训练任务[ID:{}]执行成功，状态更新为1，耗时：{}ms，分析报告：{}", taskId, costTime, analysisReport);

        } catch (Exception e) {
            // 有异常  失败
            TrainTaskService trainTaskService = getBean(TrainTaskService.class);
            TrainTask trainTask = new TrainTask();
            trainTask.setTTaskId(taskId.longValue());
            //trainTask.setTTaskStatus(0); // 0-失败
            long costTime = System.currentTimeMillis() - startTime;
            trainTask.setTRunInfo("执行失败（耗时：" + costTime + "ms）：" + e.getMessage());

            // 失败时也记录分析报告结果
            if (analysisReport != null && !analysisReport.isEmpty()) {
                trainTask.setTAnalysisReport(analysisReport);
            }

            trainTaskService.updateById(trainTask);
            log.error("训练任务[ID:{}]执行失败，状态更新为0", taskId, e);
            throw new RuntimeException("训练任务定时执行失败：" + e.getMessage(), e);

        } finally {
            // 清理ThreadLocal，避免内存泄漏
            TaskComponentExecutor componentExecutor = getBean(TaskComponentExecutor.class);
            componentExecutor.clearAnalysisReportResult();
        }
    }
}
