package com.huatek.busi.service.impl.gis.gisAssessment;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.huatek.busi.common.GisAssessEnum;
import com.huatek.busi.entity.GisAssessmentResult;
import com.huatek.busi.entity.GisAssessmentResultData;
import com.huatek.busi.entity.LabReportMarkStatistic;
import com.huatek.busi.util.*;
import com.huatek.busi.vo.BusiOfflineGisBrandVo;
import com.huatek.busi.vo.BusiParamTransformerVo;
import com.huatek.busi.vo.GisEvaVo;
import com.huatek.torch.util.uuid.Uuid;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
public class GisAssessmentCalculate {

    public static GisFormulaCal gisFormulaCalInstance = GisFormulaCal.getInstance();

    /**
     * 获取合闸不同期A、B、C三相
     *
     * @param list
     * @return
     */
    public static Map<String, String> getAllData(List<LabReportMarkStatistic> list) {
        Map<String, String> map = new HashMap<>();
        for (String key : GisAssessEnum.getKeys()) {
            if ("0051".equals(key)||"0055".equals(key)){
                continue;
            }
            map.put(key, String.valueOf(getRules(key, list)));
        }
        return map;
    }

    /**
     * 分项计算
     *
     * @return
     */
    public static Map<String, String> calculateResult(String testValue, BusiParamTransformerVo parentVo, BusiParamTransformerVo vo, int step) {
        BigDecimal wightResult = new BigDecimal(0);
        if ("1".equals(vo.getIsAttend())) {
            if (StrUtil.isAllBlank(testValue)) {
                EvaluationNameUtil.throwErrorMsg(parentVo, vo);
            }
            BigDecimal result = gisFormulaCalInstance.formulaForUpAndDown(new BigDecimal(testValue), vo.getModel(), vo.getAValue(), vo.getBValue());
            log.info("{}权重值：{}", vo.getDescription(), vo.getValue());
            wightResult = gisFormulaCalInstance.calcValue(result, vo.getValue(), parentVo.getValue());
            log.info("--->>  GIS-{}-计算结果: [{}]", vo.getDescription(), wightResult.toString());
            step += 1;
            EvaluationNameUtil.setStep(step, vo, wightResult.toString(), testValue);
        }
        Map<String, String> result = new HashMap<>();
        result.put("step", String.valueOf(step));
        result.put("result", wightResult.toString());
        return result;
    }

    /**
     * 根据打标规则获取相关数据
     *
     * @param key
     * @param list
     */
    public static String getRules(String key, List<LabReportMarkStatistic> list) {
        String rule = list.get(0).getECalculateRule();
        List<LabReportMarkStatistic> labReportMarkStatisticList = list.stream()
                .filter((LabReportMarkStatistic vo) -> vo.getERule().equals(key))
                .collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(labReportMarkStatisticList)) {
            // 最小值
            if ("001".equals(rule)) {
                return labReportMarkStatisticList.stream()
                        .map(item -> new BigDecimal(item.getCurrentValue() == null ? "0.00" : item.getCurrentValue()))
                        .min(BigDecimal::compareTo).get().toString();
                // 最大值
            } else if ("002".equals(rule)) {
                return labReportMarkStatisticList.stream()
                        .map(item -> new BigDecimal(item.getCurrentValue() == null ? "0.00" : item.getCurrentValue()))
                        .max(BigDecimal::compareTo).get().toString();
                // 平均值
            } else {
                //求平均值
                return labReportMarkStatisticList.stream()
                        .map(item -> new BigDecimal(item.getCurrentValue() == null ? "0.00" : item.getCurrentValue()))
                        .reduce(BigDecimal.ZERO, BigDecimal::add).divide(BigDecimal.valueOf(labReportMarkStatisticList.size()), 4, RoundingMode.HALF_UP).toString();
            }
        }
        return "0.00";
    }

    public static GisAssessmentResult formGisAssessmentResult(String uuid, String siteId,
                                                              String mainTreeId, String score,
                                                              String gisStatus, String healthLevelExplain,
                                                              Map<String, String> kdmsResult,
                                                              BusiOfflineGisBrandVo busiOfflineGisBrandVo,
                                                              String sydkcs, String jxjy, String type) {
        // Gis评估结果
        GisAssessmentResult gisAssessmentResult = new GisAssessmentResult();
        gisAssessmentResult.setId(uuid);
        gisAssessmentResult.setSiteId(siteId);
        gisAssessmentResult.setMainTreeId(mainTreeId);
        gisAssessmentResult.setAssessTime(LocalDateTime.now());
        gisAssessmentResult.setHealthScore(GisAssessUtilsNew.formatNumStr(score).setScale(4, RoundingMode.HALF_UP).toString());
        // 触头磨损率
        gisAssessmentResult.setHealthLevel(gisStatus);
        gisAssessmentResult.setHealthLevelExplain(healthLevelExplain);
        gisAssessmentResult.setContactWearRate(new BigDecimal(kdmsResult.get(GisCreateUtil.RELATIVE_WEAR_DEGREE_VALUE)).multiply(BigDecimal.valueOf(100)).setScale(4, RoundingMode.HALF_UP).toString());
        // 取值待定标牌中数据
        gisAssessmentResult.setExpectedUsageCount(busiOfflineGisBrandVo.getServiceTime());
        gisAssessmentResult.setRemainingUsageCount(sydkcs);
        gisAssessmentResult.setOverhaulSuggest(jxjy);
        gisAssessmentResult.setType(type);
        return gisAssessmentResult;
    }

    public static GisAssessmentResultData formResult(Map<String, String> kdmsResult, Map<String, String> yxsjResult,
                                                     Map<String, String> sf6Result, Map<String, String> yxcsResult,
                                                     String uuid, String gisId, String gisName,
                                                     String score, String gisStatus, String sydkcs, String jxjy) {
        // 最终结果
        GisAssessmentResultData result = new GisAssessmentResultData();
        // 开断磨损
        List<GisEvaVo> list1 = new ArrayList<>();
        // 运行数据
        List<GisEvaVo> list2 = new ArrayList<>();
        // 绝缘介质
        List<GisEvaVo> list3 = new ArrayList<>();
        // 运行参数
        List<GisEvaVo> list4 = new ArrayList<>();

        GisEvaVo vo11 = new GisEvaVo(GisCreateUtil.SERVICE_LIFE, kdmsResult.get(GisCreateUtil.SERVICE_LIFE), "使用年限");
        GisEvaVo vo12 = new GisEvaVo(GisCreateUtil.RELATIVE_WEAR_DEGREE, kdmsResult.get(GisCreateUtil.RELATIVE_WEAR_DEGREE), "相对磨损程度");
        GisEvaVo vo13 = new GisEvaVo(GisCreateUtil.CUMULATIVE_ACTION_TIMES, kdmsResult.get(GisCreateUtil.CUMULATIVE_ACTION_TIMES), "累计动作次数");
        list1.add(vo11);
        list1.add(vo12);
        list1.add(vo13);

        GisEvaVo vo21 = new GisEvaVo(GisCreateUtil.TIME_PARAMETER, yxsjResult.get(GisCreateUtil.TIME_PARAMETER), "时间参数");
        GisEvaVo vo22 = new GisEvaVo(GisCreateUtil.VELOCITY_CHARACTERISTICS, yxsjResult.get(GisCreateUtil.VELOCITY_CHARACTERISTICS), "速度特性");
        list2.add(vo21);
        list2.add(vo22);

        GisEvaVo vo31 = new GisEvaVo(GisCreateUtil.GAS_PRESSURE, sf6Result.get(GisCreateUtil.GAS_PRESSURE), "气体压力");
        GisEvaVo vo32 = new GisEvaVo(GisCreateUtil.MICRO_WATER_CONTENT, sf6Result.get(GisCreateUtil.MICRO_WATER_CONTENT), "微水含量");
        GisEvaVo vo33 = new GisEvaVo(GisCreateUtil.PARTIAL_DISCHARGE, sf6Result.get(GisCreateUtil.PARTIAL_DISCHARGE), "局放量");
        GisEvaVo vo34 = new GisEvaVo(GisCreateUtil.PARTIAL_DISCHARGE_COUNT, sf6Result.get(GisCreateUtil.PARTIAL_DISCHARGE_COUNT), "局放次数");
        list3.add(vo31);
        list3.add(vo32);
        list3.add(vo33);
        list3.add(vo34);

        GisEvaVo vo41 = new GisEvaVo(GisCreateUtil.WORK_ENVIRONMENT, yxcsResult.get(GisCreateUtil.WORK_ENVIRONMENT), "工作环境");
        GisEvaVo vo42 = new GisEvaVo(GisCreateUtil.APPEARANCE, yxcsResult.get(GisCreateUtil.APPEARANCE), "外观情况");
        GisEvaVo vo43 = new GisEvaVo(GisCreateUtil.MAINTENANCE_RECORD, yxcsResult.get(GisCreateUtil.MAINTENANCE_RECORD), "维修记录");
        GisEvaVo vo44 = new GisEvaVo(GisCreateUtil.Manufacturer, yxcsResult.get(GisCreateUtil.Manufacturer), "生产厂家");
        list4.add(vo41);
        list4.add(vo42);
        list4.add(vo43);
        list4.add(vo44);

        result.setId(Uuid.getUUID());
        result.setEvaluationId(uuid);
        result.setGisId(gisId);
        result.setGisName(gisName);
        result.setAssessTime(LocalDate.now());
        result.setHealthScore(GisAssessUtilsNew.formatNumStr(score).setScale(2, RoundingMode.HALF_UP).toString());
        // 触头磨损率
        result.setHealthLevel(gisStatus);
        result.setContactWearRate(kdmsResult.get(GisCreateUtil.RELATIVE_WEAR_DEGREE_VALUE));
        result.setRemainingUsageCount(sydkcs);
        result.setOverhaulSuggest(jxjy);
        result.setDkcses(kdmsResult.get(GisCreateUtil.CUMULATIVE_ACTION_TIMES_VALUE));

        result.setBreakingWear(kdmsResult.get(GisCreateUtil.BREAKING_WEAR));
        result.setOperationalData(yxsjResult.get(GisCreateUtil.OPERATIONAL_DATA));
        result.setOperationParameters(yxcsResult.get(GisCreateUtil.OPERATION_PARAMETERS));
        result.setInsulatingMedium(sf6Result.get(GisCreateUtil.INSULATING_MEDIUM));

        String json1 = JSONArray.toJSONString(list1);
        String json2 = JSONArray.toJSONString(list2);
        String json3 = JSONArray.toJSONString(list3);
        String json4 = JSONArray.toJSONString(list4);
        result.setBreakingWearDetails(json1);
        result.setOperationalDataDetails(json2);
        result.setInsulatingMediumDetails(json3);
        result.setOperationParametersDetails(json4);
        return result;
    }

    public static Map<String, String> formHealthResult(BigDecimal score) {
        Map<String, String> result = new HashMap<>();
        // 健康水平
        String gisStatus = gisFormulaCalInstance.getGisStatus(score);
        result.put("gisStatus", gisStatus);
        // 检修建议
        String jxjy = gisFormulaCalInstance.getJxjy(score);
        result.put("jxjy", jxjy);
        // 健康水平说明
        String healthLevelExplain = gisFormulaCalInstance.getJkspsm(score);
        result.put("healthLevelExplain", healthLevelExplain);
        return result;
    }

}
