package org.jeecg.modules.checkData.face.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.sax.handler.RowHandler;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.JsonObject;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.UUIDGenerator;
import org.jeecg.modules.checkData.entity.*;
import org.jeecg.modules.checkData.face.MovementRecordsMasterFace;
import org.jeecg.modules.checkData.service.*;
import org.jeecg.modules.dynamicStaticAnalysis.entity.AnalysisBatchCheckDataMap;
import org.jeecg.modules.dynamicStaticAnalysis.mapper.AnalysisAlgorithmMapper;
import org.jeecg.modules.dynamicStaticAnalysis.service.IAnalysisBatchCheckDataMapService;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
public class MovementRecordsMasterFaceImpl implements MovementRecordsMasterFace {

    @Resource
    private IMovementCourseService movementCourseService;

    @Resource
    private IMovementCourseInfoService movementCourseInfoService;

    @Resource
    private IMovementRecordsMasterService movementRecordsMasterService;

    @Resource
    private IMovementOverReportService movementOverReportService;
    @Resource
    private IMovementSectionReportService movementSectionReportService;
    @Resource
    private IMovementSummaryReportService movementSummaryReportService;
    @Resource
    private IMovementTqiKilometerReportService movementTqiKilometerReportService;
    @Resource
    private IMovementTqiKilometerStandardManagerService movementTqiKilometerStandardManagerService;
    @Resource
    private IMovementTqiReportService movementTqiReportService;
    @Resource
    private IMovementTqiStandardManagerService movementTqiStandardManagerService;
    @Resource
    private IMovementDiferenceManagerService movementDiferenceManagerService;
    @Resource
    private IMovementAdditiveInfoService movementAdditiveInfoService;

    @Resource
    private IRailInspectionEquipmentItemService railInspectionEquipmentItemService;
    @Resource
    private IRailInspectionEquipmentItemDetailService railInspectionEquipmentItemDetailService;

    @Resource
    private IAnalysisBatchCheckDataMapService analysisBatchCheckDataMapService;

    @Override
    public void saveLabourCheckItem(MovementCourse record) {
        // 保存人工项目检查表
        record.setId(UUIDGenerator.generate());
        record.setDelFlag("0");
        movementCourseService.save(record);


        // 初始化下面的格子模板
        List<MovementCourseInfo> movementCourseInfos = new ArrayList<>();
        int measurePoint = 1;
        String trackCode = "1";
        for (int i = 0; i < 24; i++) {
            MovementCourseInfo movementCourseInfo = new MovementCourseInfo();
            movementCourseInfo.setMovementMasterId(record.getMovementMasterId());
            movementCourseInfo.setMovementCourseId(record.getId());
            movementCourseInfo.setMeasurePoint(measurePoint);
            movementCourseInfo.setInfoSort(i + 1);
            movementCourseInfo.setDelFlag("0");
            movementCourseInfo.setTrackCode(trackCode);
            if (measurePoint % 8 == 0) {
                measurePoint = 1;
                trackCode = String.valueOf(Integer.valueOf(trackCode) + 1);
            } else {
                measurePoint++;
            }
            movementCourseInfos.add(movementCourseInfo);
        }
        movementCourseInfoService.saveBatch(movementCourseInfos);


        /**
         * 人工检查数据排序
         */
        labourCheckItemSort(record.getMovementMasterId());

        /**
         * 人工检查数据单元设备映射
         */
        labourCheckMappingUnitDevice(record.getMovementMasterId());

    }

    @Override
    public void updateLabourCheckItem(MovementCourse record) {
        movementCourseService.lambdaUpdate().set(MovementCourse::getCourseStartingMileage, record.getCourseStartingMileage()).set(MovementCourse::getCourseEndMileage, record.getCourseEndMileage()).set(MovementCourse::getCurveRadius, record.getCurveRadius()).set(MovementCourse::getSuperHigh, record.getSuperHigh()).set(MovementCourse::getWiden, record.getWiden()).set(MovementCourse::getSlopeRatio, record.getSlopeRatio()).set(MovementCourse::getLongExtent, record.getLongExtent()).eq(MovementCourse::getId, record.getId()).update();
    }

    @Override
    public void uploadFile(MultipartFile file, String id) {
        try {
            InputStream inputStream = file.getInputStream();
            List<MovementCourse> movementCourseList = new ArrayList<>();
            List<MovementCourseInfo> movementCourseInfoList = new ArrayList<>();

            // 1.excel导入List<List<Object>> 中
            CurrentRowHandler currentRowHandler = new CurrentRowHandler();
            ExcelUtil.readBySax(inputStream, 0, currentRowHandler);


            // 2.循环列数解析数据
            int column = currentRowHandler.rowRecords.get(0).size();
            int sort = 0;
            for (int i = 0; i < column; i++) {

                // 2.1 解析检查项目 获取 起止里程,曲线半径,超高,加宽,顺坡率,线路全长
                // 2.1.1 获取起止里程来判断该条记录是否获取
                List<Object> startAndEndColumn = currentRowHandler.rowRecords.get(3);
                List<Object> courseColumn = currentRowHandler.rowRecords.get(4);
                if (ObjectUtil.isNotEmpty(startAndEndColumn.get(i))) {
                    String startingAndRowDataStr = startAndEndColumn.get(i).toString();
                    String courseDataStr = courseColumn.get(i).toString();

                    // ① 获取起止里程,为空跳过这个表格，不解析
                    int startIndex = startingAndRowDataStr.indexOf("起止里程：");
                    int endIndex = startingAndRowDataStr.indexOf("，站线");
                    String startingAndEndingMileageStr = "";
                    if (startIndex != -1 && endIndex != -1) {
                        startingAndEndingMileageStr = startingAndRowDataStr.substring(startIndex + "起止里程：".length(), endIndex).trim();
                        startingAndEndingMileageStr = startingAndEndingMileageStr.replace(" ", "").replace("/", "");
                    }
                    if (ObjectUtil.isEmpty(startingAndEndingMileageStr)) {
                        continue;
                    }
                    String[] mileages = startingAndEndingMileageStr.split("-");
                    String startMileageStr = mileages[0].replace("K", "").replace("+", "");
                    String endMileageStr = mileages[1].replace("K", "").replace("+", "");
                    BigDecimal startMileage = Convert.toBigDecimal(startMileageStr);
                    BigDecimal endMileage = Convert.toBigDecimal(endMileageStr);

                    // ② 获取曲线半径，可能为空，‘/’ 视为空
                    startIndex = startingAndRowDataStr.indexOf("曲线半径");
                    endIndex = startingAndRowDataStr.indexOf("m");
                    String curveRadiusStr = "";
                    if (startIndex != -1 && endIndex != -1) {
                        curveRadiusStr = startingAndRowDataStr.substring(startIndex + "曲线半径".length(), endIndex);
                        curveRadiusStr = curveRadiusStr.replace("/", "").trim();
                    }
                    BigDecimal curveRadius = Convert.toBigDecimal(curveRadiusStr);

                    // ③ 获取超高，可能为空，‘/’ 视为空
                    startIndex = courseDataStr.indexOf("超高");
                    endIndex = courseDataStr.indexOf("加宽");
                    String superHighStr = "";
                    if (startIndex != -1 && endIndex != -1) {
                        superHighStr = courseDataStr.substring(startIndex + "超高".length(), endIndex);
                        superHighStr = superHighStr.replace("，", "").replace("mm", "").replace("/", "").trim();
                    }
                    BigDecimal superHigh = Convert.toBigDecimal(superHighStr);

                    // ④ 获取加宽，可能为空，‘/’ 视为空
                    startIndex = courseDataStr.indexOf("加宽");
                    endIndex = courseDataStr.indexOf("顺坡率");
                    String widenStr = "";
                    if (startIndex != -1 && endIndex != -1) {
                        widenStr = courseDataStr.substring(startIndex + "加宽".length(), endIndex);
                        widenStr = widenStr.replace("，", "").replace("mm", "").replace("/", "").trim();
                    }
                    BigDecimal widen = Convert.toBigDecimal(widenStr);

                    // ⑤ 获取顺坡率，可能为空，‘/’ 视为空
                    startIndex = courseDataStr.indexOf("顺坡率");
                    endIndex = courseDataStr.indexOf("线路全长");
                    String slopeRatioStr = "";
                    if (startIndex != -1 && endIndex != -1) {
                        slopeRatioStr = courseDataStr.substring(startIndex + "顺坡率".length(), endIndex);
                        slopeRatioStr = slopeRatioStr.replace("，", "").replace("‰", "").replace("/", "").trim();
                    }
                    BigDecimal slopeRatio = Convert.toBigDecimal(slopeRatioStr);

                    // ⑥ 获取长度，可能为空，‘/’ 视为空
                    startIndex = courseDataStr.indexOf("线路全长");
                    String longExtentStr = "";
                    if (startIndex != -1) {
                        longExtentStr = courseDataStr.substring(startIndex + "线路全长".length());
                        longExtentStr = longExtentStr.replace("/", "").replace("米", "").trim();
                    }
                    BigDecimal longExtent = Convert.toBigDecimal(longExtentStr);

                    // ⑦ 解析备注
                    Object remarkObj = currentRowHandler.rowRecords.get(14).get(i + 3);
                    String remark = null;
                    if (ObjectUtil.isNotEmpty(remarkObj)) {
                        remark = remarkObj.toString();
                    }


                    sort++;
                    MovementCourse movementCourse = new MovementCourse();
                    movementCourse.setId(UUIDGenerator.generate());
                    movementCourse.setMovementMasterId(id);
                    movementCourse.setCourseStartingMileage(startMileage);
                    movementCourse.setCourseEndMileage(endMileage);
                    movementCourse.setCurveRadius(curveRadius);
                    movementCourse.setSuperHigh(superHigh);
                    movementCourse.setWiden(widen);
                    movementCourse.setSlopeRatio(slopeRatio);
                    movementCourse.setLongExtent(longExtent);
                    movementCourse.setDelFlag("0");
                    movementCourse.setRemark(remark);
                    movementCourse.setSort(sort);
                    movementCourseList.add(movementCourse);

                    // 2.2.2  解析项目里面的明细
                    // 2.2.2.1 单独定义轨号
                    Object trackCode = null;

                    // 2.2.2.2 循环获取 轨号,轨距,水平,三角坑,方向,高低,结构,整改
                    int measurePoint = 1;
                    for (int j = 2; j < 26; j++) {
                        int position = i + j;

                        // 获取轨号,
                        if (j == 2 || j == 10 || j == 18) {
                            List<Object> trackCodeList = currentRowHandler.rowRecords.get(6);
                            trackCode = trackCodeList.get(position);
                        }
                        if (ObjectUtil.isEmpty(trackCode)) {
                            throw JeecgBootException.error("【" + startMileage + "~" + endMileage + "】内请输入轨号");
                        }

                        // 获取轨距
                        List<Object> trackGaugeList = currentRowHandler.rowRecords.get(7);
                        Object trackGauge = trackGaugeList.get(position);


                        //获取水平
                        List<Object> levelList = currentRowHandler.rowRecords.get(8);
                        Object level = levelList.get(position);


                        //获取三角坑
                        List<Object> triangularPitList = currentRowHandler.rowRecords.get(9);
                        Object triangularPit = triangularPitList.get(position);

                        //获取方向
                        List<Object> directionList = currentRowHandler.rowRecords.get(10);
                        Object direction = directionList.get(position);

                        //获取高低
                        List<Object> heightList = currentRowHandler.rowRecords.get(11);
                        Object height = heightList.get(position);

                        //获取结构
                        List<Object> structureList = currentRowHandler.rowRecords.get(12);
                        Object structure = structureList.get(position);

                        //获取整改
                        List<Object> rectificationList = currentRowHandler.rowRecords.get(13);
                        Object rectification = rectificationList.get(position);


                        MovementCourseInfo movementCourseInfo = new MovementCourseInfo();
                        movementCourseInfo.setId(UUIDGenerator.generate());
                        movementCourseInfo.setDelFlag("0");
                        movementCourseInfo.setMovementMasterId(id);
                        movementCourseInfo.setMovementCourseId(movementCourse.getId());
                        movementCourseInfo.setInfoSort(j - 1);
                        movementCourseInfo.setMeasurePoint(measurePoint);
                        movementCourseInfo.setTrackCode(Convert.toStr(trackCode));
                        movementCourseInfo.setTrackGauge(Convert.toStr(trackGauge));
                        movementCourseInfo.setLevel(Convert.toStr(level));
                        movementCourseInfo.setTriangularPit(Convert.toStr(triangularPit));
                        movementCourseInfo.setDirection(Convert.toStr(direction));
                        movementCourseInfo.setHeight(Convert.toStr(height));
                        movementCourseInfo.setStructure(Convert.toStr(structure));
                        movementCourseInfo.setRectification(Convert.toStr(rectification));
                        movementCourseInfoList.add(movementCourseInfo);

                        if (measurePoint % 8 == 0) {
                            measurePoint = 1;
                        } else {
                            measurePoint++;
                        }
                    }
                }
            }

            // 保存之前先删除
            movementCourseService.lambdaUpdate().eq(MovementCourse::getMovementMasterId, id).remove();
            movementCourseInfoService.lambdaUpdate().eq(MovementCourseInfo::getMovementMasterId, id).remove();

            if (ObjectUtil.isNotEmpty(movementCourseInfoList)) {
                movementCourseInfoService.saveBatch(movementCourseInfoList);
            }
            if (ObjectUtil.isNotEmpty(movementCourseList)) {
                movementCourseService.saveBatch(movementCourseList);
            }

        } catch (IOException e) {
            throw JeecgBootException.error(e.getMessage());
        }
    }

    @Override
    public void delete(String id, String type) {

        List<AnalysisBatchCheckDataMap> existAnalysisList = analysisBatchCheckDataMapService.lambdaQuery()
                .eq(AnalysisBatchCheckDataMap::getEkId, id)
                .list();
        if (ObjectUtil.isNotEmpty(existAnalysisList)) {
            Optional<String> optionalStr = existAnalysisList.stream()
                    .map(AnalysisBatchCheckDataMap::getAnalysisBatchCode)
                    .reduce((analysisBatchCode1, analysisBatchCode2) -> analysisBatchCode1 + "," + analysisBatchCode2);
            String msg = "该数据下关联分析批次:【" + optionalStr.get() + "】";
            throw JeecgBootException.error(msg);
        }

        if ("1".equals(type)) {
            //人工静态检查相关
            //删除里程详情
            movementCourseInfoService.lambdaUpdate().eq(MovementCourseInfo::getMovementMasterId, id).remove();
            //删除里程相关
            movementCourseService.lambdaUpdate().eq(MovementCourse::getMovementMasterId, id).remove();
        } else if ("2".equals(type)) {
            // 删除里程
            railInspectionEquipmentItemService.lambdaUpdate().eq(RailInspectionEquipmentItem::getRailInspectionEquipmentId, id).remove();
            // 删除里程明细
            railInspectionEquipmentItemDetailService.lambdaUpdate().eq(RailInspectionEquipmentItemDetail::getRailInspectionEquipmentId, id).remove();
        } else if ("4".equals(type)) {
            //删除添乘仪详情
            movementAdditiveInfoService.lambdaUpdate().eq(MovementAdditiveInfo::getMovementMasterId, id).remove();
        } else if ("3".equals(type)) {
            //删除轨检车-》轨道动态几何尺寸容许值差管理值
            movementDiferenceManagerService.lambdaUpdate().eq(MovementDiferenceManager::getMovementMasterId, id).remove();
            //删除轨检车-》超限记录报告
            movementOverReportService.lambdaUpdate().eq(MovementOverReport::getMovementMasterId, id).remove();
            //删除轨检车-》区段总结报告
            movementSectionReportService.lambdaUpdate().eq(MovementSectionReport::getMovementMasterId, id).remove();
            //删除轨检车-》公里总结报告表
            movementSummaryReportService.lambdaUpdate().eq(MovementSummaryReport::getMovementMasterId, id).remove();
            //删除轨检车-》TQI公里总结报告
            movementTqiKilometerReportService.lambdaUpdate().eq(MovementTqiKilometerReport::getMovementMasterId, id).remove();
            //删除轨检车-》TQI公里状态评定标准
            movementTqiKilometerStandardManagerService.lambdaUpdate().eq(MovementTqiKilometerStandardManager::getMovementMasterId, id).remove();
            //删除轨检车-》TQI总结报告
            movementTqiReportService.lambdaUpdate().eq(MovementTqiReport::getMovementMasterId, id).remove();
            //删除轨检车-》200m区段轨道不平顺质量指数TQI管理标准(单位：mm)
            movementTqiStandardManagerService.lambdaUpdate().eq(MovementTqiStandardManager::getMovementMasterId, id).remove();
        }
        //删除动静态几何尺寸数据
        movementRecordsMasterService.lambdaUpdate().eq(MovementRecordsMaster::getId, id).remove();
    }


    /**
     * 当前行处理器
     */
    private static class CurrentRowHandler implements RowHandler {
        public CurrentRowHandler() {
            this.rowRecords = new ArrayList<>();
        }

        private List<List<Object>> rowRecords;

        @Override
        public void handle(int sheetIndex, long rowIndex, List<Object> rowList) {
            rowRecords.add(rowList);
        }


    }

    /**
     * 人工检查数据映射单元设备
     *
     * @param movementMasterId
     */
    private void labourCheckMappingUnitDevice(String movementMasterId) {
    }

    /**
     * 人工检查数据
     *
     * @param movementMasterId
     */
    private void labourCheckItemSort(String movementMasterId) {
        // 检查项目list
        List<MovementCourse> movementCourseList = movementCourseService.lambdaQuery().eq(MovementCourse::getMovementMasterId, movementMasterId).orderByAsc(MovementCourse::getCourseStartingMileage).list();


        // 检查项目明细list
        List<MovementCourseInfo> movementCourseInfoList = movementCourseInfoService.lambdaQuery().eq(MovementCourseInfo::getMovementMasterId, movementMasterId).orderByAsc(MovementCourseInfo::getInfoSort).list();
        Map<String, List<MovementCourseInfo>> movementCourseInfoMap = movementCourseInfoList.stream().collect(Collectors.groupingBy(MovementCourseInfo::getMovementCourseId));


        for (int i = 0; i < movementCourseList.size(); i++) {
            int sort = i + 1;
            MovementCourse movementCourse = movementCourseList.get(i);
            movementCourse.setSort(sort);


            // 修改明细的轨号

            List<MovementCourseInfo> movementCourseInfos = movementCourseInfoMap.get(movementCourse.getId());
            int incr = 2;
            int currentCheckNum = i + 1;
            String trackCode = String.valueOf(currentCheckNum * 3 - incr);
            for (int j = 0; j < movementCourseInfos.size(); j++) {
                if (j != 0 && j % 8 == 0) {
                    incr = incr - 1;
                    trackCode = String.valueOf(currentCheckNum * 3 - incr);
                }
                MovementCourseInfo movementCourseInfo = movementCourseInfos.get(j);
                movementCourseInfo.setTrackCode(trackCode);
            }
        }

        movementCourseService.updateBatchById(movementCourseList);
        movementCourseInfoService.updateBatchById(movementCourseInfoList);
    }
}
