package org.jeecg.modules.dynamicStaticAnalysis.algorithm;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.convert.Converter;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import org.jeecg.modules.checkData.dynamicStaticGeometricData.entity.RailInspectionEquipmentItem;
import org.jeecg.modules.checkData.dynamicStaticGeometricData.entity.RailInspectionEquipmentItemDetail;
import org.jeecg.modules.checkData.dynamicStaticGeometricData.service.IRailInspectionEquipmentItemDetailService;
import org.jeecg.modules.checkData.dynamicStaticGeometricData.service.IRailInspectionEquipmentItemService;
import org.jeecg.modules.checkData.equipmentCheckData.entity.MovementCourse;
import org.jeecg.modules.checkData.equipmentCheckData.entity.MovementCourseInfo;
import org.jeecg.modules.checkData.equipmentCheckData.service.IMovementCourseInfoService;
import org.jeecg.modules.checkData.equipmentCheckData.service.IMovementCourseService;
import org.jeecg.modules.dynamicStaticAnalysis.entity.AnalysisBatch;
import org.jeecg.modules.dynamicStaticAnalysis.entity.AnalysisBatchCheckDataMap;
import org.jeecg.modules.dynamicStaticAnalysis.mapper.AnalysisAlgorithmMapper;
import org.jeecg.modules.dynamicStaticAnalysis.service.IAnalysisBatchCheckDataMapService;
import org.jeecg.modules.dynamicStaticAnalysis.service.IAnalysisBatchService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;

/**
 * 分析算法
 */
@Service
public class AnalysisAlgorithm {
    @Resource
    private AnalysisAlgorithmMapper analysisAlgorithmMapper;
    @Resource
    private IAnalysisBatchService analysisBatchService;
    @Resource
    private IAnalysisBatchCheckDataMapService analysisBatchCheckDataMapService;
    @Resource
    private IMovementCourseInfoService movementCourseInfoService;
    @Resource
    private IMovementCourseService movementCourseService;
    @Resource
    private IRailInspectionEquipmentItemService railInspectionEquipmentItemService;
    @Resource
    private IRailInspectionEquipmentItemDetailService railInspectionEquipmentItemDetailService;

    /**
     * 分析
     */
    public void analysis(String analysisBatchId) {
        // 1.映射单元格
        // 1.1 获取分析批次数据
        AnalysisBatch analysisBatch = analysisBatchService.getById(analysisBatchId);
        List<AnalysisBatchCheckDataMap> analysisBatchCheckDataMapList = analysisBatchCheckDataMapService.lambdaQuery()
                .eq(AnalysisBatchCheckDataMap::getAnalysisBatchId, analysisBatchId)
                .list();
        // 1.2 按公里数正序排序所有道岔，钢轨，曲线，竖曲线
        List<Map<String, Object>> unitDeviceList = analysisAlgorithmMapper.getUnitDevice(analysisBatch.getLightRailId(), analysisBatch.getLineAliasId());

        Map<String, Map<String, Object>> unitDeviceTable = new TreeMap<>();
        // 1.3 获取检查数据
        for (AnalysisBatchCheckDataMap checkDataMap : analysisBatchCheckDataMapList) {


            // 检查数据类型 1-人工静态检查 2-轨检仪静态检查 3-轨检车检查 4-添乘仪检查
            if (1 == checkDataMap.getEkType()) {
                // 1 获取人工检查数据
                List<MovementCourse> checkItemList = movementCourseService.lambdaQuery()
                        .eq(MovementCourse::getMovementMasterId, checkDataMap.getEkId())
                        .list();
                List<MovementCourseInfo> checkItemItemDetailList = movementCourseInfoService.lambdaQuery()
                        .eq(MovementCourseInfo::getMovementMasterId, checkDataMap.getEkId())
                        .list();
                Map<String, List<MovementCourseInfo>> checkItemItemDetailMap = checkItemItemDetailList.stream()
                        .collect(Collectors.groupingBy(MovementCourseInfo::getMovementCourseId));

                // 2 循环遍历检查项目比较【开始-结束】来映射关联关系
                for (MovementCourse checkItem : checkItemList) {
                    // 2.1 这里可能出现开始时间比结束时间大的情况
                    BigDecimal checkItemStartingMileage = checkItem.getCourseStartingMileage();
                    BigDecimal checkItemEndMileage = checkItem.getCourseEndMileage();
                    if (checkItemStartingMileage.compareTo(checkItemEndMileage) > 0) {
                        checkItemStartingMileage = checkItem.getCourseEndMileage();
                        checkItemEndMileage = checkItem.getCourseStartingMileage();
                    }


                    // 2.2 单元设备中心里程落在检查项目【开始-结束】这个区间视为这个区间的单元设备
                    for (Map<String, Object> unitDevice : unitDeviceList) {
                        BigDecimal startMileage = Convert.toBigDecimal(unitDevice.get("startMileage"));
                        BigDecimal endMileage = Convert.toBigDecimal(unitDevice.get("endMileage"));
                        BigDecimal centerMileage = startMileage.add(endMileage).divide(new BigDecimal("2"), 3, RoundingMode.HALF_UP);
                        unitDevice.put("centerMileage", centerMileage);
                        // 2.2.1 命中检查项目
                        if (checkItemStartingMileage.compareTo(centerMileage) <= 0 && checkItemEndMileage.compareTo(centerMileage) > 0) {
                            List<MovementCourseInfo> movementCourseInfos = checkItemItemDetailMap.get(checkItem.getId());
                            if (ObjectUtil.isNotEmpty(movementCourseInfos)) {
                                // 1 处理3个格子映射问题
                                Map<String, List<MovementCourseInfo>> trackCodeMap = movementCourseInfos.stream()
                                        .collect(Collectors.groupingBy(MovementCourseInfo::getTrackCode));
                                int size = trackCodeMap.size();
                                BigDecimal averageDec = checkItemEndMileage.subtract(checkItemStartingMileage).divide(new BigDecimal(size), 3, RoundingMode.HALF_UP);
                                List<String> trackCodes = trackCodeMap.keySet().stream()
                                        .mapToInt(Integer::valueOf)
                                        .sorted()
                                        .mapToObj(String::valueOf)
                                        .collect(Collectors.toList());
                                BigDecimal currentStartMileage = checkItemStartingMileage;
                                BigDecimal currentEndEndMileage = checkItemStartingMileage.add(averageDec);
                                for (String trackCode : trackCodes) {
                                    // 2.命中格子
                                    if (currentStartMileage.compareTo(centerMileage) <= 0 && currentEndEndMileage.compareTo(centerMileage) > 0) {
                                        String unitCode = Convert.toStr(unitDevice.get("unitCode"));
                                        // 人工检查数据
                                        List<MovementCourseInfo> labourCheck = trackCodeMap.get(trackCode);
                                        unitDevice.put("labourCheck", labourCheck);

                                        unitDeviceTable.putIfAbsent(unitCode, unitDevice);
                                    } else {
                                        currentStartMileage = currentEndEndMileage;
                                        currentEndEndMileage = currentEndEndMileage.add(averageDec);
                                    }
                                }

                            }
                        }
                    }

                }
            } else if (2 == checkDataMap.getEkType()) {
                // 1 获取轨检仪静态检查
                List<RailInspectionEquipmentItem> checkItemList = railInspectionEquipmentItemService.lambdaQuery()
                        .eq(RailInspectionEquipmentItem::getRailInspectionEquipmentId, checkDataMap.getEkId())
                        .list();
                List<RailInspectionEquipmentItemDetail> checkItemItemDetailList = railInspectionEquipmentItemDetailService.lambdaQuery()
                        .eq(RailInspectionEquipmentItemDetail::getRailInspectionEquipmentId, checkDataMap.getEkId())
                        .list();
                Map<String, List<RailInspectionEquipmentItemDetail>> checkItemItemDetailMap = checkItemItemDetailList.stream()
                        .collect(Collectors.groupingBy(RailInspectionEquipmentItemDetail::getRailInspectionEquipmentId));

                // 2 循环遍历检查项目比较【开始-结束】来映射关联关系
                for (RailInspectionEquipmentItem checkItem : checkItemList) {
                    // 2.1 这里可能出现开始时间比结束时间大的情况
                    BigDecimal checkItemStartingMileage = checkItem.getCourseStartingMileage();
                    BigDecimal checkItemEndMileage = checkItem.getCourseEndMileage();
                    if (checkItemStartingMileage.compareTo(checkItemEndMileage) > 0) {
                        checkItemStartingMileage = checkItem.getCourseEndMileage();
                        checkItemEndMileage = checkItem.getCourseStartingMileage();
                    }


                    // 2.2 单元设备中心里程落在检查项目【开始-结束】这个区间视为这个区间的单元设备
                    for (Map<String, Object> unitDevice : unitDeviceList) {
                        BigDecimal startMileage = Convert.toBigDecimal(unitDevice.get("startMileage"));
                        BigDecimal endMileage = Convert.toBigDecimal(unitDevice.get("endMileage"));
                        BigDecimal centerMileage = startMileage.add(endMileage).divide(new BigDecimal("2"), 3, RoundingMode.HALF_UP);
                        unitDevice.put("centerMileage", centerMileage);

                        // 2.2.1 命中检查项目
                        if (checkItemStartingMileage.compareTo(centerMileage) <= 0 && checkItemEndMileage.compareTo(centerMileage) > 0) {
                            List<RailInspectionEquipmentItemDetail> movementCourseInfos = checkItemItemDetailMap.get(checkItem.getId());
                            if (ObjectUtil.isNotEmpty(movementCourseInfos)) {

                            }
                        }
                    }
                }
            } else if (3 == checkDataMap.getEkType()) {

            } else {

            }
        }


        System.out.println("JSONObject.toJSONString(unitDeviceTable) = " + JSONObject.toJSONString(unitDeviceTable));

        // 1.映射单元格


        // 2.评分
    }
}