package com.xvji.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xvji.domain.Component;
import com.xvji.domain.TrainTask;
import com.xvji.mapper.TrainTaskMapper;
import com.xvji.quartz.domain.SysJob;
import com.xvji.quartz.service.ISysJobService;
import com.xvji.service.ComponentService;
import com.xvji.service.TrainTaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
import java.util.List;

/**
 * 训练任务服务
 */
@Service
public class TrainTaskServiceImpl extends ServiceImpl<TrainTaskMapper, TrainTask> implements TrainTaskService {

    @Autowired
    private ComponentService componentService;
    // 注入定时任务Service
    @Autowired
    private ISysJobService sysJobService;

    // 日志对象
    private static final Logger log = LoggerFactory.getLogger(TrainTaskServiceImpl.class);

    /**
     * 新增训练任务并关联单个组件
     * 默认填充任务创建时间、任务状态
     */
    @Transactional
    @Override
    public boolean addTrainTaskWithComponent(TrainTask trainTask, Component component) {
        if (trainTask.getTCreateTime() == null) {
            trainTask.setTCreateTime(new Date()); // 默认当前时间
        }
        if (trainTask.getTTaskStatus() == null) {
            //trainTask.setTTaskStatus(0); // 默认初始状态（1-成功，0-失败）
        }

        // 保存训练任务
        boolean taskSaved = this.save(trainTask);
        if (!taskSaved) {
            throw new RuntimeException("训练任务保存失败");
        }

        component.setTaskId(trainTask.getTTaskId());
        component.setTaskType(0);
        if (component.getIsEnable() == null) {
            component.setIsEnable(true); // 组件默认启用
        }
        return componentService.save(component);
    }

    /**
     * 查询所有训练任务
     */
    @Override
    public List<TrainTask> getAllTrainTasks() {
        return baseMapper.selectList(null);
    }

    /**
     * 根据id删除训练任务 同时删除关联组件
     * @param taskId 训练任务id
     * @return
     */
    @Transactional
    @Override
    public boolean deleteTrainTaskWithComponents(Long taskId) {
        TrainTask trainTask = this.getById(taskId);
        if (trainTask == null) {
            log.warn("训练任务[ID:{}]不存在，无需删除", taskId);
            return false;
        }

        //  删除关联组件
        QueryWrapper<Component> componentQueryWrapper = new QueryWrapper<>();
        componentQueryWrapper.eq("TASK_ID", taskId).eq("TASK_TYPE", 0);
        componentService.remove(componentQueryWrapper);

        // 删除训练任务
        this.removeById(taskId);

        // 同步删除关联的定时任务
        String targetInvokeTarget = "com.xvji.quartz.TaskQuartzJob.executeTrainTask(" + taskId + ")";
        sysJobService.deleteJobByParam(targetInvokeTarget);
        log.info("训练任务[ID:{}]及关联组件、定时任务已删除", taskId);

        return true;
    }





    /**
     * 训练任务定时任务同步的核心方法
     * @param task 训练任务对象
     */
    private void syncToSysJob(TrainTask task) {
        // 防循环：如果是定时任务同步过来的更新（名称带[SYNCED]），跳过反向同步
        if (task.getTTaskName() != null && task.getTTaskName().contains("[SYNCED]")) {
            log.info("训练任务[ID:{}]是定时任务同步的更新，跳过反向同步", task.getTTaskId());
            // 移除标记，避免显示异常
            task.setTTaskName(task.getTTaskName().replace("[SYNCED]", ""));
            this.updateById(task);
            return;
        }

        Long taskId = task.getTTaskId();
        // 精确匹配定时任务的invoke_target
        String exactInvokeTarget = "com.xvji.quartz.TaskQuartzJob.executeTrainTask(" + taskId + ")";
        SysJob sysJob = sysJobService.selectJobByParam(exactInvokeTarget);

        if (sysJob == null) {
            log.error("未找到训练任务[ID:{}]关联的定时任务，同步失败", taskId);
            return;
        }

        // 校验Cron表达式有效性
        String cron = task.getTCronExpression();
        if (cron != null && !sysJobService.checkCronExpressionIsValid(cron)) {
            log.error("训练任务[ID:{}]的Cron表达式[{}]无效，同步终止", taskId, cron);
            throw new RuntimeException("Cron表达式无效：" + cron);
        }

        // 同步核心字段到定时任务
        sysJob.setJobName(task.getTTaskName()); // 名称同步
        sysJob.setCronExpression(cron); // Cron同步
        sysJob.setStatus(task.getTTaskStatus().toString()); // 状态同步（Integer→String）
        sysJob.setJobGroup("TRAIN_TASK"); // 固定任务组

        // 执行定时任务更新
        boolean syncSuccess = sysJobService.updateSysJob(sysJob);
        if (syncSuccess) {
            log.info("训练任务[ID:{}]成功同步到定时任务[ID:{}]", taskId, sysJob.getJobId());
        } else {
            log.error("训练任务[ID:{}]同步到定时任务失败", taskId);
        }
    }

    @Transactional
    @Override
    public boolean updateTrainTask(TrainTask task) {
        // 先更新训练任务表
        boolean updateResult = this.updateById(task);
        if (!updateResult) {
            log.error("训练任务[ID:{}]更新失败，同步定时任务终止", task.getTTaskId());
            return false;
        }

        // 调用已有同步方法，同步到定时任务
        syncToSysJob(task);
        return true;
    }




}