package com.cmvr.aima.service.impl;

import java.util.List;
import java.util.UUID;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.spring.service.impl.ServiceImpl;
import com.cmvr.aima.domain.dto.AimaTaskInstanceQuery;
import com.cmvr.aima.domain.vo.AimaTaskInstanceVo;
import com.cmvr.common.exception.ServiceException;
import com.cmvr.common.utils.SecurityUtils;
import com.cmvr.test.flow.control.FlowControlService;
import com.cmvr.test.flow.runtime.engine.FlowTaskRuntimeService;
import com.cmvr.test.flow.runtime.event.FlowExecutionModuleCodes;
import com.cmvr.test.model.vo.TeTaskExecuteNormalVO;
import com.cmvr.test.service.ITeTaskOrchestrationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import com.cmvr.common.utils.DateUtils;
import com.cmvr.aima.mapper.AimaTaskInstanceMapper;
import com.cmvr.aima.domain.AimaTaskInstance;
import com.cmvr.aima.service.IAimaTaskInstanceService;
import com.cmvr.aima.enums.AimaTaskStatusEnum;
import com.cmvr.aima.service.IAimaTaskService;
import com.cmvr.aima.domain.AimaTask;
import org.springframework.transaction.annotation.Transactional;

/**
 * 爱玛任务执行实例Service业务层处理
 * 
 * @author cmvr-iot
 * @since 2026-06-22
 */
@Service
@Transactional
public class AimaTaskInstanceServiceImpl extends ServiceImpl<AimaTaskInstanceMapper, AimaTaskInstance> implements IAimaTaskInstanceService {
    @Autowired
    private AimaTaskInstanceMapper aimaTaskInstanceMapper;

    @Autowired
    private IAimaTaskService aimaTaskService;

    @Autowired
    private ITeTaskOrchestrationService teTaskOrchestrationService;

    @Autowired
    @Lazy
    private FlowTaskRuntimeService flowTaskRuntimeService;

    @Autowired
    @Lazy
    private FlowControlService flowControlService;

    @Override
    public AimaTaskInstance selectAimaTaskInstanceById(String id) {
        return aimaTaskInstanceMapper.selectAimaTaskInstanceById(id);
    }

    @Override
    public List<AimaTaskInstance> selectAimaTaskInstanceList(AimaTaskInstance aimaTaskInstance) {
        return aimaTaskInstanceMapper.selectAimaTaskInstanceList(aimaTaskInstance);
    }

    @Override
    public List<AimaTaskInstanceVo> selectAimaTaskInstanceVoList(AimaTaskInstanceQuery query) {
        return aimaTaskInstanceMapper.selectAimaTaskInstanceVoList(query);
    }

    @Override
    public int insertAimaTaskInstance(AimaTaskInstance aimaTaskInstance) {
        if (aimaTaskInstance.getId() == null || aimaTaskInstance.getId().isEmpty()) {
            aimaTaskInstance.setId(UUID.randomUUID().toString().replace("-", ""));
        }
        aimaTaskInstance.setStatus(AimaTaskStatusEnum.NOT_STARTED.getCode());
        aimaTaskInstance.setCreateTime(DateUtils.getNowDate());
        aimaTaskInstance.setCreateBy(SecurityUtils.getUsername());
        // 获取测试用例数量
        AimaTask aimaTask = aimaTaskService.selectAimaTaskById(aimaTaskInstance.getTaskId());
        if (aimaTask != null && aimaTask.getTestCaseCount() != null) {
            aimaTaskInstance.setTotalCases(aimaTask.getTestCaseCount());
        }
        return aimaTaskInstanceMapper.insertAimaTaskInstance(aimaTaskInstance);
    }

    @Override
    public int updateAimaTaskInstance(AimaTaskInstance aimaTaskInstance) {
        // 校验状态，只有未执行可以修改
        if (AimaTaskStatusEnum.NOT_STARTED.getCode() != aimaTaskInstance.getStatus()) {
            throw new ServiceException("只有未执行状态的任务实例才能修改");
        }
        aimaTaskInstance.setUpdateTime(DateUtils.getNowDate());
        aimaTaskInstance.setUpdateBy(SecurityUtils.getUsername());
        // 获取测试用例数量
        AimaTask aimaTask = aimaTaskService.selectAimaTaskById(aimaTaskInstance.getTaskId());
        if (aimaTask != null && aimaTask.getTestCaseCount() != null) {
            aimaTaskInstance.setTotalCases(aimaTask.getTestCaseCount());
        }
        return aimaTaskInstanceMapper.updateAimaTaskInstance(aimaTaskInstance);
    }

    @Override
    public int deleteAimaTaskInstanceByIds(String[] ids) {
        // 校验状态，只有未执行可以删除
        for (String id : ids) {
            AimaTaskInstance instance = aimaTaskInstanceMapper.selectAimaTaskInstanceById(id);
            if (instance != null && AimaTaskStatusEnum.NOT_STARTED.getCode() != instance.getStatus()) {
                throw new ServiceException("只有未执行状态的任务实例才能删除");
            }
        }
        return aimaTaskInstanceMapper.deleteAimaTaskInstanceByIds(ids);
    }

    @Override
    public int deleteAimaTaskInstanceById(String id) {
        return aimaTaskInstanceMapper.deleteAimaTaskInstanceById(id);
    }

    /**
     * 开始执行任务实例
     */
    @Override
    public int startInstance(String id) {
        AimaTaskInstance instance = aimaTaskInstanceMapper.selectAimaTaskInstanceById(id);
        if (instance == null) {
            throw new ServiceException("任务实例不存在");
        }
        if (AimaTaskStatusEnum.NOT_STARTED.getCode() != instance.getStatus()) {
            throw new ServiceException("只有待执行状态的任务实例才能开始执行");
        }
        AimaTaskInstance update = new AimaTaskInstance();
        update.setId(id);
        update.setStatus(AimaTaskStatusEnum.RUNNING.getCode());
        update.setStartTime(DateUtils.getNowDate());
        update.setUpdateTime(DateUtils.getNowDate());
        update.setUpdateBy(SecurityUtils.getUsername());


        
        AimaTask aimaTask = aimaTaskService.selectAimaTaskById(instance.getTaskId());
        JSONObject runParams = new JSONObject();
        // 从test模块的任务编排中获取所有的检测项id
        if (aimaTask != null && aimaTask.getTaskConfigId() != null) {
            teTaskOrchestrationService.queryByTaskId(aimaTask.getTaskConfigId())
                .forEach(item -> runParams.put(item.getItemId(), new JSONObject()));
        }
        // 调用流程引擎执行
        String insId = flowTaskRuntimeService.executeTask(
            TeTaskExecuteNormalVO.builder()
                .taskId(aimaTask.getTaskConfigId())
                .moduleCode(FlowExecutionModuleCodes.AIMA)
                .runParams(runParams)
                .build()
        );
        update.setTaskInsId(insId);
        return aimaTaskInstanceMapper.updateAimaTaskInstance(update);
    }

    /**
     * 暂停任务实例
     */
    @Override
    public int pauseInstance(String id) {
        AimaTaskInstance instance = aimaTaskInstanceMapper.selectAimaTaskInstanceById(id);
        if (instance == null) {
            throw new ServiceException("任务实例不存在");
        }
        if (AimaTaskStatusEnum.RUNNING.getCode() != instance.getStatus()) {
            throw new ServiceException("只有执行中状态的任务实例才能暂停");
        }
        AimaTaskInstance update = new AimaTaskInstance();
        update.setId(id);
        update.setStatus(AimaTaskStatusEnum.PAUSED.getCode());
        update.setUpdateTime(DateUtils.getNowDate());
        update.setUpdateBy(SecurityUtils.getUsername());
        flowControlService.pause(instance.getTaskInsId());
        return aimaTaskInstanceMapper.updateAimaTaskInstance(update);
    }

    /**
     * 终止任务实例
     */
    @Override
    public int stopInstance(String id) {
        AimaTaskInstance instance = aimaTaskInstanceMapper.selectAimaTaskInstanceById(id);
        if (instance == null) {
            throw new ServiceException("任务实例不存在");
        }
        if (AimaTaskStatusEnum.NOT_STARTED.getCode() != instance.getStatus() 
            && AimaTaskStatusEnum.RUNNING.getCode() != instance.getStatus()) {
            throw new ServiceException("已完成或已取消的任务实例不能终止");
        }
        AimaTaskInstance update = new AimaTaskInstance();
        update.setId(id);
        update.setStatus(AimaTaskStatusEnum.STOPPED.getCode());
        update.setEndTime(DateUtils.getNowDate());
        update.setUpdateTime(DateUtils.getNowDate());
        update.setUpdateBy(SecurityUtils.getUsername());
        flowControlService.stop(instance.getTaskInsId());
        return aimaTaskInstanceMapper.updateAimaTaskInstance(update);
    }

    /**
     * 恢复任务实例（从暂停恢复为执行中）
     */
    @Override
    public int resumeInstance(String id) {
        AimaTaskInstance instance = aimaTaskInstanceMapper.selectAimaTaskInstanceById(id);
        if (instance == null) {
            throw new ServiceException("任务实例不存在");
        }
        if (AimaTaskStatusEnum.PAUSED.getCode() != instance.getStatus()) {
            throw new ServiceException("只有已暂停状态的任务实例才能恢复");
        }
        AimaTaskInstance update = new AimaTaskInstance();
        update.setId(id);
        update.setStatus(AimaTaskStatusEnum.RUNNING.getCode());
        update.setUpdateTime(DateUtils.getNowDate());
        update.setUpdateBy(SecurityUtils.getUsername());
        flowControlService.resume(instance.getTaskInsId());
        return aimaTaskInstanceMapper.updateAimaTaskInstance(update);
    }

    /**
     * 更新任务实例进度
     */
    @Override
    public void updateProgress(String instanceId, Double progress) {
        AimaTaskInstance update = new AimaTaskInstance();
        update.setId(instanceId);
        update.setProgress(progress);
        update.setUpdateTime(DateUtils.getNowDate());
        aimaTaskInstanceMapper.updateAimaTaskInstance(update);
    }
}
