package com.cmvr.ti.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
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.core.domain.entity.SysDictData;
import com.cmvr.common.exception.GlobalException;
import com.cmvr.evaluation.model.domain.AeEvaluation;
import com.cmvr.evaluation.model.domain.AeIndicatorEntity;
import com.cmvr.evaluation.model.dto.AeIResultDTO;
import com.cmvr.evaluation.model.vo.AeViEvaluationVO;
import com.cmvr.evaluation.service.AeIndicatorService;
import com.cmvr.evaluation.service.IAeEvaluationService;
import com.cmvr.system.service.ISysDictTypeService;
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.TeQueryTaskOrchestraItemVO;
import com.cmvr.test.model.vo.TeTaskExecuteProjectVO;
import com.cmvr.test.model.vo.TeTaskOrchestraVO;
import com.cmvr.test.service.ITeDetectionItemService;
import com.cmvr.test.service.ITeTaskConfigInfoService;
import com.cmvr.test.service.ITeTaskOrchestrationService;
import com.cmvr.ti.mapper.TiProjectMapper;
import com.cmvr.ti.model.domain.TiProject;
import com.cmvr.ti.model.domain.TiVehicleFunction;
import com.cmvr.ti.service.ITiProjectService;
import com.cmvr.ti.service.ITiVehicleFunctionService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class TiProjectServiceImpl extends ServiceImpl<TiProjectMapper, TiProject> implements ITiProjectService {

    private final ITeTaskOrchestrationService taskOrchestrationService;
    private final ITeDetectionItemService detectionItemService;
    private final ITeTaskConfigInfoService taskConfigInfoService;
    private final FlowTaskRuntimeService flowTaskRuntimeService;
    private final ITiVehicleFunctionService tiVehicleFunctionService;
    private final ISysDictTypeService dictTypeService;
    private final StringRedisTemplate redisTemplate;
    private final IAeEvaluationService aeEvaluationService;
    private final AeIndicatorService aeIndicatorService;
    private final ITiVehicleFunctionService vehicleFunctionService;

    @Override
    public TiProject selectTiProjectByProjectId(String projectId) {
        return this.getById(projectId);
    }

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

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertTiProject(TiProject tiProject) {
        // 校验功能ID是否属于同一车型配置
        List<Long> ids = JSON.parseArray(tiProject.getTestFuncIds(), Long.class);

        List<TiVehicleFunction> functions = tiVehicleFunctionService.queryByIds(ids);

        if (functions.size() != ids.size()) {
            throw new GlobalException("存在无效的功能ID");
        }

        if (functions.stream()
                .map(TiVehicleFunction::getVehicleConfigId)
                .distinct()
                .count() != 1) {
            throw new GlobalException("功能ID不属于同一车型配置");
        }

        tiProject.setStatus("0");
        int insert = this.baseMapper.insert(tiProject);
        TeTaskConfigInfo taskConfigInfo = new TeTaskConfigInfo();
        taskConfigInfo.setRunMode(RunModeEnum.TI_PROJECT.name());
        taskConfigInfo.setId(tiProject.getProjectId());
        taskConfigInfo.setStatus("0");
        taskConfigInfo.setTaskName(StrUtil.format("{}_{}", RunModeEnum.TI_PROJECT, tiProject.getProjectName()));
        taskConfigInfoService.save(taskConfigInfo);

        // 插入编排项
        TeDetectionItem item = detectionItemService.selectTeDetectionItemBySceneType(FlowSceneTypeEnum.TI_TOUCH.getSceneCode());
        TeTaskOrchestraVO teTaskOrchestraVO = new TeTaskOrchestraVO();
        teTaskOrchestraVO.setTaskId(taskConfigInfo.getId());
        teTaskOrchestraVO.setItemIds(Collections.singletonList(item.getId()));
        taskOrchestrationService.insertTeTaskOrchestration(teTaskOrchestraVO);
        return insert;
    }

    @Override
    public int updateTiProject(TiProject tiProject) {
        return this.baseMapper.updateById(tiProject);
    }

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

    @Override
    public List<TeQueryTaskOrchestraItemVO> queryExecuteRunParams(String projectId) {
        return taskOrchestrationService.queryByTaskId(projectId);
    }

    @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<TiProject>()
//                        .eq(TiProject::getProjectId, taskExecuteProjectVO.getProjectId())
//                        .set(TiProject::getStatus, "0")
//        );
        return instId;
    }

    @Override
    public TeTaskInst getTeTaskInst(String projectId) {
        return null;
    }

    @Override
    public String queryExecuteInstId(String projectId) {
        return "";
    }

    @Override
    public boolean updateProjectStatus(String projectId, Integer status) {
        LambdaUpdateWrapper<TiProject> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(TiProject::getProjectId, projectId)
                .set(TiProject::getStatus, status);
        return this.update(null, wrapper);
    }

    // 功能ID -> 音频地址
    private final Map<String, String> AUDIO_PATH_MAP = new HashMap<String, String>() {{
        put("8", "http://192.168.0.100:9000/cmvr-iot/AUDIO/20260310/1773108837127.wav"); // 播放音乐
        put("12", "http://192.168.0.100:9000/cmvr-iot/AUDIO/20260310/1773108916488.wav"); // 打开导航
        put("9", "http://192.168.0.100:9000/cmvr-iot/AUDIO/20260310/1773108933968.wav"); // 能量回收
    }};

    // 功能ID -> 视频地址
    private final Map<String, String> VIDEO_PATH_MAP = new HashMap<String, String>() {{
        put("8",  "http://192.168.0.100:9000/cmvr-iot/VIDEO/20260310/1773108955700.mp4"); // 播放音乐
        put("12", "http://192.168.0.100:9000/cmvr-iot/VIDEO/20260310/1773108967164.mp4"); // 打开导航
        put("9",  "http://192.168.0.100:9000/cmvr-iot/VIDEO/20260310/1773108978124.mp4"); // 能量回收
    }};

    @Override
    public void executeTiEvaluation(List<Long> funcIds) {
        AeEvaluation aeEvaluation = new AeEvaluation();
        aeEvaluation.setAeType(RunModeEnum.TI_PROJECT.name());
        aeEvaluation.setInstId(IdUtil.fastSimpleUUID());
        aeEvaluation.setTaskId("aadb21a32e7990456b866e844a7d4a54");
        aeEvaluation.setItemId(IdUtil.fastSimpleUUID());

        // todo 触控交互评估
        String taskId = aeEvaluation.getTaskId();
        updateProjectStatus(taskId, 1); // 执行中
        // 模拟流程运行
//        try {
//            Thread.sleep(30000);
//        } catch (InterruptedException e) {
//            throw new RuntimeException(e);
//        }


        // 查字典
        List<SysDictData> tiFunctionConfig = dictTypeService.selectDictDataByType("ti_function_config");
        Map<String, String> functionMap = tiFunctionConfig.stream()
                .collect(Collectors.toMap(
                        SysDictData::getDictValue,
                        SysDictData::getDictLabel
                ));

        // 构建评估任务列表
        List<AeEvaluation> evaluations = new LinkedList<>();
        for (Long funcId : funcIds) {
            TiVehicleFunction byId = vehicleFunctionService.getById(funcId);
            String funcName = functionMap.get(byId.getFuncKey());
            AeEvaluation eval = new AeEvaluation();
            BeanUtil.copyProperties(aeEvaluation, eval);
            eval.setAeId(IdUtil.fastSimpleUUID());
            eval.setStatus(0);           // 待评估
            eval.setAvContent(funcName);
            eval.setAudioPath(AUDIO_PATH_MAP.get(byId.getFuncKey()));
            eval.setVideoPath(VIDEO_PATH_MAP.get(byId.getFuncKey()));
            evaluations.add(eval);
        }

        try {
            // 入库
            aeEvaluationService.saveBatch(evaluations);

            // 提交评估
            for (AeEvaluation e : evaluations) {
                redisTemplate.opsForList()
                        .rightPush("ae:evaluation:queue", JSON.toJSONString(e));
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public AeViEvaluationVO queryEvaluation(String projectId) {
        // 1. 查询项目
        TiProject project = getById(projectId);

        // 2. 查询评估数据（允许不完整）
        List<AeEvaluation> evaluations = aeEvaluationService.queryEvaluationByProjectId(projectId);
        if (CollUtil.isEmpty(evaluations)) {
            throw new GlobalException(StrUtil.format("暂无项目id为{}的数据", projectId));
        }

        // 3. 获取指标定义
        List<AeIndicatorEntity> indicators =
                aeIndicatorService.getChildrenByParentIdWithLevelLimit(
                        project.getIndicatorId(), 4, 1
                );

        List<AeViEvaluationVO.AeItemDetail> itemDetails = new ArrayList<>();

        int failureCount = 0;
        for (AeEvaluation evaluation : evaluations) {
            AeViEvaluationVO.AeItemDetail itemDto = new AeViEvaluationVO.AeItemDetail();
            itemDto.setAeId(evaluation.getAeId());
            itemDto.setContent(evaluation.getAvContent());
            AeIResultDTO dto = JSON.parseObject(evaluation.getResult(), AeIResultDTO.class);
            itemDto.setItemResponseTime(dto.getResponseTime());
            itemDto.setStatus(evaluation.getStatus());

            boolean success = "成功".equals(dto.getOverallResult());

            if (!success) {
                itemDto.setFailureReason(dto.getFailureReason());
                failureCount++;
            }

            itemDto.setVideoPath(dto.getVideoPath());
            itemDto.setExecutionDetail(dto.getExecutionDetail());

            itemDetails.add(itemDto);
        }

        // 计算成功率
        Long successRate = (long) (((evaluations.size() - failureCount) * 100.0) / evaluations.size());

        //成功率得分
        Long score = calculateSuccessRateScore(successRate, indicators);


        AeViEvaluationVO vo = new AeViEvaluationVO();
        vo.setItemDetails(itemDetails);
        vo.setSuccessRate(successRate);
        vo.setSuccessRateScore(score);
        return vo;
    }

    private Long calculateSuccessRateScore(Long successRate, List<AeIndicatorEntity> indicators) {
        // 查找成功率指标
        AeIndicatorEntity successRateIndicator = findIndicatorByName(indicators, "成功率");

        if (successRateIndicator == null) {
            return 0L; // 如果没有匹配的成功率指标，返回 0 分
        }
        List<AeIndicatorEntity> children = successRateIndicator.getChildren();

        long score = 0L;
        for (AeIndicatorEntity child : children) {
            // 子指标的比较值（例如响应时间阈值）和符号（如 <, <=, >, >=）
            BigDecimal compareValue1 = child.getCompareNum1();
            BigDecimal compareValue2 = child.getCompareNum2();
            String symbol = child.getSymbol();

            // 4. 根据符号和阈值判断响应时间是否符合子指标的规则，计算得分
            if (compareRange(successRate, compareValue1, compareValue2, symbol)) {
                score = child.getScore().longValue(); // 得分等于子指标的得分
                break; // 找到符合条件的子指标后直接返回得分
            }
        }
        return score;
    }

    private AeIndicatorEntity findIndicatorByName(List<AeIndicatorEntity> indicators, String indicatorName) {
        for (AeIndicatorEntity indicator : indicators) {
            if (indicator.getName().equals(indicatorName)) {
                return indicator;
            }
        }
        return null; // 如果找不到，返回null
    }

    // 处理区间比较（例如：<=，>=）
    private boolean compareRange(Long itemResponseTime, BigDecimal compareValue1, BigDecimal compareValue2, String symbol) {
        // 如果 compareValue1 > compareValue2，交换两者
        if (compareValue1.compareTo(compareValue2) > 0) {
            BigDecimal temp = compareValue1;
            compareValue1 = compareValue2;
            compareValue2 = temp;
        }

        switch (symbol) {
            case "≤":
                return itemResponseTime <= compareValue2.longValue() && itemResponseTime >= compareValue1.longValue();
            case "<":
                return itemResponseTime < compareValue2.longValue() && itemResponseTime >= compareValue1.longValue();
            case ">":
                return itemResponseTime > compareValue1.longValue() && itemResponseTime <= compareValue2.longValue();
            case "≥":
                return itemResponseTime >= compareValue1.longValue() && itemResponseTime <= compareValue2.longValue();
            default:
                return false;
        }
    }
}
