package com.cmvr.inspection.service.impl;

import java.util.List;
import java.util.UUID;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cmvr.common.exception.ServiceException;
import com.cmvr.common.utils.SecurityUtils;
import com.cmvr.inspection.domain.InspectionTask;
import com.cmvr.inspection.domain.dto.InspectionTaskInstanceQuery;
import com.cmvr.inspection.domain.vo.InspectionTaskInstanceVo;
import com.cmvr.inspection.enums.TaskStatusEnum;
import com.cmvr.inspection.service.IInspectionTaskService;
import com.cmvr.test.flow.control.FlowControlService;
import com.cmvr.test.flow.runtime.engine.FlowTaskRuntimeService;
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.inspection.mapper.InspectionTaskInstanceMapper;
import com.cmvr.inspection.domain.InspectionTaskInstance;
import com.cmvr.inspection.service.IInspectionTaskInstanceService;

/**
 * 巡检任务执行实例Service业务层处理
 * 
 * @author cmvr-iot
 * @since 2026-06-01
 */
@Service
public class InspectionTaskInstanceServiceImpl extends ServiceImpl<InspectionTaskInstanceMapper, InspectionTaskInstance>     implements IInspectionTaskInstanceService
{
    @Autowired
    private IInspectionTaskService inspectionTaskService;
    @Autowired
    private InspectionTaskInstanceMapper inspectionTaskInstanceMapper;

    @Autowired
    private ITeTaskOrchestrationService teTaskOrchestrationService;

    @Autowired
    @Lazy
    private FlowTaskRuntimeService flowTaskRuntimeService;
    @Autowired
    @Lazy
    private FlowControlService flowControlService;

    /**
     * 查询巡检任务执行实例视图详情（包含关联信息）
     * 
     * @param id 巡检任务执行实例主键
     * @return 巡检任务执行实例视图
     */
    @Override
    public InspectionTaskInstanceVo selectInspectionTaskInstanceVoById(String id)
    {
        return inspectionTaskInstanceMapper.selectInspectionTaskInstanceVoById(id);
    }

    /**
     * 查询巡检任务执行实例列表
     * 
     * @param inspectionTaskInstanceQuery 巡检任务执行实例
     * @return 巡检任务执行实例
     */
    @Override
    public List<InspectionTaskInstanceVo> selectInspectionTaskInstanceList(InspectionTaskInstanceQuery inspectionTaskInstanceQuery)
    {
        return inspectionTaskInstanceMapper.selectInspectionTaskInstanceVoList(inspectionTaskInstanceQuery);
    }

    /**
     * 新增巡检任务执行实例
     * 
     * @param inspectionTaskInstance 巡检任务执行实例
     * @return 结果
     */
    @Override
    public int insertInspectionTaskInstance(InspectionTaskInstance inspectionTaskInstance)
    {
        // 生成UUID作为主键
        if (inspectionTaskInstance.getId() == null || inspectionTaskInstance.getId().isEmpty()) {
            inspectionTaskInstance.setId(UUID.randomUUID().toString().replace("-", ""));
        }
        inspectionTaskInstance.setStatus(TaskStatusEnum.NOT_STARTED.getCode());
        inspectionTaskInstance.setCreateTime(DateUtils.getNowDate());
        inspectionTaskInstance.setCreateBy(SecurityUtils.getUsername());
        // 获取点位数量
        InspectionTask inspectionTask = inspectionTaskService.selectInspectionTaskById(inspectionTaskInstance.getTaskId());
        inspectionTaskInstance.setWaypointCount(inspectionTask.getWaypointCount());
        return inspectionTaskInstanceMapper.insertInspectionTaskInstance(inspectionTaskInstance);
    }

    /**
     * 修改巡检任务执行实例
     * 
     * @param inspectionTaskInstance 巡检任务执行实例
     * @return 结果
     */
    @Override
    public int updateInspectionTaskInstance(InspectionTaskInstance inspectionTaskInstance)
    {
        // 校验状态，只有未执行可以修改
        if (TaskStatusEnum.NOT_STARTED.getCode() != inspectionTaskInstance.getStatus()) {
            throw new ServiceException("只有未执行状态的任务实例才能修改");
        }
        inspectionTaskInstance.setUpdateTime(DateUtils.getNowDate());
        inspectionTaskInstance.setUpdateBy(SecurityUtils.getUsername());
        // 获取点位数量
        InspectionTask inspectionTask = inspectionTaskService.selectInspectionTaskById(inspectionTaskInstance.getTaskId());
        inspectionTaskInstance.setWaypointCount(inspectionTask.getWaypointCount());
        return inspectionTaskInstanceMapper.updateInspectionTaskInstance(inspectionTaskInstance);
    }

    /**
     * 批量删除巡检任务执行实例
     * 
     * @param ids 需要删除的巡检任务执行实例主键
     * @return 结果
     */
    @Override
    public int deleteInspectionTaskInstanceByIds(String[] ids)
    {
        // 校验状态，只有未执行可以删除
        for (String id : ids) {
            InspectionTaskInstance instance = inspectionTaskInstanceMapper.selectInspectionTaskInstanceById(id);
            if (TaskStatusEnum.NOT_STARTED.getCode() != instance.getStatus()) {
                throw new ServiceException("只有未执行状态的任务实例才能删除");
            }
        }
        return inspectionTaskInstanceMapper.deleteInspectionTaskInstanceByIds(ids);
    }

    /**
     * 开始执行任务实例
     */
    @Override
    public int startInstance(String id)
    {
        InspectionTaskInstance instance = inspectionTaskInstanceMapper.selectInspectionTaskInstanceById(id);
        if (instance == null) {
            throw new ServiceException("任务实例不存在");
        }
        if (TaskStatusEnum.NOT_STARTED.getCode() != instance.getStatus()) {
            throw new ServiceException("只有待执行状态的任务实例才能开始执行");
        }
        InspectionTaskInstance update = new InspectionTaskInstance();
        update.setId(id);
        update.setStatus(TaskStatusEnum.RUNNING.getCode());
        update.setStartTime(DateUtils.getNowDate());
        update.setUpdateTime(DateUtils.getNowDate());
        update.setUpdateBy(SecurityUtils.getUsername());
        InspectionTask inspectionTask = inspectionTaskService.selectInspectionTaskById(instance.getTaskId());
        JSONObject runParams = new JSONObject();
        // 获取所有的检测项id
        teTaskOrchestrationService.queryByTaskId(inspectionTask.getTaskConfigId()).forEach(item -> runParams.put(item.getItemId(), new JSONObject()));
        // 调用真正的执行
        String insId = flowTaskRuntimeService.executeTask(TeTaskExecuteNormalVO.builder().taskId(inspectionTask.getTaskConfigId()).runParams(runParams).build());
        update.setTaskInsId(insId);
        return inspectionTaskInstanceMapper.updateInspectionTaskInstance(update);
    }

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

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

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