package com.cmvr.vi.service.impl;

import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cmvr.common.exception.GlobalException;
import com.cmvr.evaluation.service.IAeEvaluationService;
import com.cmvr.test.enums.FlowSceneTypeEnum;
import com.cmvr.test.enums.RunModeEnum;
import com.cmvr.test.flow.runtime.engine.FlowTaskRuntimeService;
import com.cmvr.test.model.domain.TeDetectionItem;
import com.cmvr.test.model.domain.TeTaskConfigInfo;
import com.cmvr.test.model.domain.TeTaskInst;
import com.cmvr.test.model.vo.TeQueryProjectOrchestraItemVO;
import com.cmvr.test.model.vo.TeTaskExecuteProjectVO;
import com.cmvr.test.service.ITeDetectionItemService;
import com.cmvr.test.service.ITeTaskConfigInfoService;
import com.cmvr.test.service.ITeTaskInstService;
import com.cmvr.vi.mapper.ViProjectMapper;
import com.cmvr.vi.model.domain.ViProject;
import com.cmvr.vi.model.domain.ViScheme;
import com.cmvr.vi.service.IViProjectService;
import com.cmvr.vi.service.IViSchemeService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 语音交互-项目Service业务层处理
 *
 * @author cmvr-iot
 */
@Service
@RequiredArgsConstructor
public class ViProjectServiceImpl extends ServiceImpl<ViProjectMapper, ViProject> implements IViProjectService {

    private final FlowTaskRuntimeService flowTaskRuntimeService;
    private final IViSchemeService viSchemeService;
    private final ITeDetectionItemService detectionItemService;
    private final ITeTaskConfigInfoService taskConfigInfoService;
    private final ITeTaskInstService taskInstService;
    private final IAeEvaluationService aeEvaluationService;

    @Override
    public ViProject selectViProjectByProjectId(String projectId) {
        return this.getById(projectId);
    }

    @Override
    public List<ViProject> selectViProjectList(ViProject viProject) {
        LambdaQueryWrapper<ViProject> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(ObjUtil.isNotEmpty(viProject.getProjectName()), ViProject::getProjectName, viProject.getProjectName())
                .eq(ObjUtil.isNotEmpty(viProject.getStatus()), ViProject::getStatus, viProject.getStatus());
        return this.list(wrapper);
    }

    @Override
    public int insertViProject(ViProject viProject) {
        int insert = this.baseMapper.insert(viProject);
        TeTaskConfigInfo taskConfigInfo = new TeTaskConfigInfo();
        taskConfigInfo.setRunMode(RunModeEnum.VI_PROJECT.name());
        taskConfigInfo.setId(viProject.getProjectId());
        taskConfigInfo.setStatus("0");
        taskConfigInfo.setTaskName(StrUtil.format("{}_{}", RunModeEnum.VI_PROJECT, viProject.getProjectName()));
        taskConfigInfoService.save(taskConfigInfo);
        return insert;
    }

    @Override
    public int updateViProject(ViProject viProject) {
        return this.baseMapper.updateById(viProject);
    }

    @Override
    public int deleteViProjectByProjectIds(String[] projectIds) {
        taskConfigInfoService.deleteTeTaskConfigInfoByIds(projectIds);
        return this.baseMapper.deleteBatchIds(Arrays.asList(projectIds));
    }

    @Override
    public List<TeQueryProjectOrchestraItemVO> queryExecuteRunParams(String projectId) {
        // 方案信息
        List<ViScheme> viSchemes = viSchemeService.querySchemesByProjectId(projectId);

        List<TeQueryProjectOrchestraItemVO> result = new ArrayList<>();

        for (ViScheme scheme : viSchemes) {
            // 根据场景类型查找对应检测项流程
            String sceneTypeKey = FlowSceneTypeEnum.fromCode(scheme.getSceneType()).getSceneCode();
            TeDetectionItem item = detectionItemService.selectTeDetectionItemBySceneType(sceneTypeKey);
            if (item == null) {
                continue;
            }

            TeQueryProjectOrchestraItemVO vo = new TeQueryProjectOrchestraItemVO();
            vo.setSchemeId(scheme.getSchemeId());
            vo.setSchemeName(scheme.getSchemeName());
            vo.setItemId(item.getId());
            vo.setConfig(item.getConfig());
            vo.setItemName(item.getDetectName());
            vo.setOrderNum(scheme.getSort());

            result.add(vo);
        }

        // 重新归一化 1..N
        for (int i = 0; i < result.size(); i++) {
            result.get(i).setOrderNum(i + 1);
        }

        return result;
    }

    @Override
    public String executeProject(TeTaskExecuteProjectVO taskExecuteProjectVO) {
        TeTaskExecuteProjectVO normalVO = new TeTaskExecuteProjectVO();
        normalVO.setProjectId(taskExecuteProjectVO.getProjectId());
        normalVO.setRunParams(taskExecuteProjectVO.getRunParams());
        normalVO.setTerminalId(taskExecuteProjectVO.getTerminalId());
        String instId = flowTaskRuntimeService.executeProjectTask(normalVO);
        this.update(
                new LambdaUpdateWrapper<ViProject>()
                        .eq(ViProject::getProjectId, taskExecuteProjectVO.getProjectId())
                        .set(ViProject::getStatus, "0")
        );
        return instId;
    }

    @Override
    public String queryExecuteInstId(String projectId) {
        TeTaskInst latestTaskInst = getTeTaskInst(projectId);
        return latestTaskInst.getId();
    }

    @Override
    public TeTaskInst getTeTaskInst(String projectId) {
        LambdaQueryWrapper<ViProject> wrapperProject = Wrappers.lambdaQuery(ViProject.class);
        wrapperProject.eq(ViProject::getProjectId, projectId)
                .eq(ViProject::getStatus, "0");
        ViProject project = this.getOne(wrapperProject);
        if (ObjUtil.isEmpty(project)) {
            throw new GlobalException("项目id为 [{}] 的任务不存在或未执行！", projectId);
        }
        LambdaQueryWrapper<TeTaskInst> wrapper = Wrappers.lambdaQuery(TeTaskInst.class);
        wrapper.eq(TeTaskInst::getTaskId, projectId)
                .orderByDesc(TeTaskInst::getCreateTime)
                .last("LIMIT 1");
        TeTaskInst latestTaskInst = taskInstService.getOne(wrapper);
        return latestTaskInst;
    }

    @Override
    public Object queryEvaluation(String projectId) {
        // 查询项目信息
        ViProject project = getById(projectId);
        // 查询对应的实例id
        String instId = queryExecuteInstId(projectId);
        // 查询对应检测项信息
        List<TeQueryProjectOrchestraItemVO> items = queryExecuteRunParams(projectId);


        // 查询对应评估信息
//        aeEvaluationService

        return null;

    }
}
