package com.pqs9000.serviceimpl.report;

import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.StrUtil;
import com.njcn.mapper.configuration.OverLimitMapper;
import com.njcn.pojo.configuration.OverLimit;
import com.pqs9000.pojo.report.*;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.njcn.mapper.configuration.LineDetailMapper;
import com.njcn.pojo.configuration.LineDetail;
import com.njcn.utils.AppConfig;
import com.pqs9000.mapper.report.ExcelReportMapper;
import com.pqs9000.mapper.report.GetICurrentMapper;
import com.pqs9000.mapper.report.GetVirtualDataMapper;
import com.pqs9000.pojo.report.enumReport.EnumPass;
import com.pqs9000.service.report.FpyReportService;
import com.pqs9000.service.report.GetFpyService;
import tk.mybatis.mapper.entity.Example;

@Service
public class FpyReportServiceImpl implements FpyReportService {
    @Autowired
    private GetFpyService getFpyService;
    @Autowired
    private GetVirtualDataMapper getVirtualDataMapper;
    @Autowired
    private ExcelReportMapper excelReportMapper;
    @Autowired
    private GetICurrentMapper getICurrentMapper;
    @Autowired
    private LineDetailMapper lineDetailMapper;
    @Autowired
    private AppConfig appConfig;

    @Autowired
    private OverLimitMapper overLimitMapper;

    private String vTmp = "";
    private String iTmp = "";

    @Override
    @Deprecated
    public List<FpyReportData> fpyExcel(List<Integer> lineIndexs, Date startTime, Date endTime) {

        System.out.println("开始执行" + LocalDateTime.now());
        List<FpyReportData> result = new ArrayList<>();

        List<ReportValue> listICurrent = new ArrayList<>();
        Condition condition = new Condition(appConfig);
        condition.setStart(startTime);
        condition.setEnd(endTime);
        condition.setB(true);


        //List<Map<Integer,Float>> inMap = excelReportMapper.getIntegrityList(lineIndexs, startTime, endTime);

        System.out.println("开始执行循环任务" + LocalDateTime.now());
        for (Integer lineIndex : lineIndexs) {
            FpyReportData tmp = new FpyReportData();
            listICurrent.clear();

            tmp = excelReportMapper.integrityDataByIndex(lineIndex, startTime, endTime);

            LineDetail line = lineDetailMapper.selectByPrimaryKey((long) lineIndex);

            condition.setPointIndex(lineIndex);


            List<FpyDataByType> fpyData = getFpyService.getFpy(condition);

            vTmp = "";
            iTmp = "";
            if (tmp == null) {
                continue;
            } else {
                String harmDes = "";
                String powerDes = "";
                for (FpyDataByType fpy : fpyData) {
                    switch (fpy.getEnumPass().getDescribe()) {
                        case "UHARM_0_OVERTIME":
                            powerDes += judgeVFpy(fpy.getListS());
                            break;
                        case "IHARM_0_OVERTIME":
                            powerDes += judgeIFpy(fpy.getListS(), condition);
                            break;
                        case "VOLTAGE_DEV_OVERTIME":
                            powerDes += judgeVOLTAGE(fpy.getListS());
                            break;
                        case "UBALANCE_OVERTIME":
                            powerDes += judgeTHREE(fpy.getListT(), line.getPtType());
                            break;
                        case "UABERRANCE_OVERTIME":
                            powerDes += judgeTHDV(fpy.getListS());
                            break;
                        case "FREQ_DEV_OVERTIME":
                            powerDes += judgeRATE(fpy.getListT());
                            break;
                        case "FLICKER_OVERTIME":
                            powerDes += judgeFLICKER(fpy.getListS());
                            break;
                    }
                }

                if (vTmp.equals("") && iTmp.equals("")) {
                    harmDes = "合格";
                } else {
                    harmDes += vTmp + iTmp;
                }
                tmp.setHarmDes(harmDes);
                tmp.setPowerDes(powerDes);

                result.add(tmp);
            }
        }
        System.out.println("结束循环任务" + LocalDateTime.now());
        return result;
    }

    private String judgeVOLTAGE(List<FpyRate> list) {
        String result = "";
        if (list == null) {
            return result;
        }
        if (list.get(0).getRate() < 100) {
            result += "电压偏差" + list.get(0).getRate() + "%;";
        }
        return result;
    }

    private String judgeTHREE(List<FpyRate> list, Integer pttype) {
        String result = "";
        if (pttype != 0 || list == null) {
            return result;
        }
        if (list.get(0).getRate() < 100) {
            result += "三相电压不平衡度" + list.get(0).getRate() + "%;";
        }
        return result;
    }

    private String judgeTHDV(List<FpyRate> list) {
        String result = "";
        if (list == null) {
            return result;
        }
        if (list.get(0).getRate() < 100) {
            result += "电压总谐波畸变率" + list.get(0).getRate() + "%;";
        }
        return result;
    }

    private String judgeRATE(List<FpyRate> list) {
        String result = "";
        if (list == null) {
            return result;
        }
        if (list.get(0).getRate() < 100) {
            result += "频率偏差" + list.get(0).getRate() + "%;";
        }
        return result;
    }

    private String judgeFLICKER(List<FpyRate> list) {
        String result = "";
        if (list == null) {
            return result;
        }
        if (list.get(0).getRate() < 100) {
            result += "电压长时闪变" + list.get(0).getRate() + "%;";
        }
        return result;
    }

    private String judgeVFpy(List<FpyRate> list) {
        String result = "";
        if (list == null) {
            return result;
        }
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).getRate() < 95) {
                result += String.valueOf(i + 2) + "次电压含有率合格率" + list.get(i).getRate() + "%;";
                vTmp = "谐波电压;";
            }
        }
        return result;
    }

    private String judgeIFpy(List<FpyRate> list, Condition condition) {
        String result = "";
        if (list == null) {
            return result;
        }
        List<String> lists = new ArrayList<>();
        List<String> rates = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).getRate() < 95) {
                lists.add(String.valueOf(i + 2));
                rates.add(String.valueOf(list.get(i).getRate()));
            }
        }
        if (lists.size() > 0) {
            Double count = Math.ceil(getVirtualDataMapper.getTotalCP95Data(condition).intValue() * 0.05);
            condition.setCount(count);

            List<Map<String, Object>> iDate = getICurrentMapper.getIMaxLimit(condition, lists);

            for (int ii = 0; ii < lists.size(); ii++) {
                String code = "I_" + lists.get(ii) + "_CP95";
                result += lists.get(ii) + "次谐波电流合格率" + rates.get(ii) + "%,";
                result += "限值" + iDate.get(1).get(code).toString() + "A,最大值" + String.format("%.2f", iDate.get(0).get(code)) + "A;";
                iTmp = "谐波电流;";
            }
        }
        return result;
    }

    private void transformData(List<ReportTarget> list, List<ReportValue> listValue, List<Pass> listOverlimit, boolean... b) {
        int offset = b[0] ? 3 : 1;
        offset = (b.length == 2 && !b[1]) ? 4 : offset;
        int i = 0;

        for (int index = 0; index < listValue.size(); index += offset) {
            ReportTarget reportTarget = new ReportTarget();
            List<ReportValue> list1 = new ArrayList<>();
            list1.addAll(listValue.subList(index, index + offset));
            reportTarget.setList(list1);
            Float overLimit = listOverlimit.get(i).getOverLimit();
            reportTarget.setOverLimit(overLimit);

            switch (listOverlimit.get(i).getCode()) {
                case 1:
                    for (int k = 0; k < reportTarget.getList().size(); k++) {
                        if (null == reportTarget.getList().get(k).getFmaxValue()) {
                            break;
                        } else if (reportTarget.getList().get(k).getFmaxValue().floatValue() > overLimit.floatValue()) {
                            reportTarget.setPass(EnumPass.NOPASS.getCode());
                            break;
                        } else {
                            reportTarget.setPass(EnumPass.PASS.getCode());
                        }
                    }
                    break;
                case 2:
                    for (int k = 0; k < reportTarget.getList().size(); k++) {
                        if (null == reportTarget.getList().get(k).getMinValue()) {
                            break;
                        } else if (reportTarget.getList().get(k).getMinValue().floatValue() > overLimit.floatValue()) {
                            reportTarget.setPass(EnumPass.NOPASS.getCode());
                            break;
                        } else {
                            reportTarget.setPass(EnumPass.PASS.getCode());
                        }
                    }
                    break;
                case 3:
                    for (int k = 0; k < reportTarget.getList().size(); k++) {
                        if (null == reportTarget.getList().get(k).getMeanValue()) {
                            break;
                        } else if (reportTarget.getList().get(k).getMeanValue().floatValue() > overLimit.floatValue()) {
                            reportTarget.setPass(EnumPass.NOPASS.getCode());
                            break;
                        } else {
                            reportTarget.setPass(EnumPass.PASS.getCode());
                        }
                    }
                    break;
                case 4:
                    for (int k = 0; k < reportTarget.getList().size(); k++) {
                        if (null == reportTarget.getList().get(k).getCp95Value()) {
                            break;
                        } else if (reportTarget.getList().get(k).getCp95Value().floatValue() > overLimit.floatValue()) {
                            reportTarget.setPass(EnumPass.NOPASS.getCode());
                            break;
                        } else {
                            reportTarget.setPass(EnumPass.PASS.getCode());
                        }
                    }
                    break;
                default:
                    break;
            }

            i++;
            list.add(reportTarget);
        }
    }


    /**
     * 合格率报告
     *
     * @author cdf
     * @date 2023/5/26
     */
    @Override
    public List<FpyReportData> qualifiedRate(List<Integer> lineIds, Date startTime, Date endTime) {
        List<FpyReportData> result = new ArrayList<>();


        List<Map<String, BigDecimal>> limitRateCalDTOList = excelReportMapper.getLimitRateData(lineIds, startTime, endTime);

        List<Map<String, BigDecimal>> dayIMapList = excelReportMapper.getLimitRateDataIHarm(lineIds, startTime, endTime);
        Map<Integer, Map<String, BigDecimal>> mapMap = dayIMapList.stream().collect(Collectors.toMap(it->it.get("MYINDEX").intValue(),Function.identity()));



        if (CollectionUtil.isNotEmpty(limitRateCalDTOList)) {

            List<LineBaseData> integrityList = excelReportMapper.getIntegrityList(lineIds, startTime, endTime);
            Map<Integer, LineBaseData> integerLineBaseDataMap = integrityList.stream().collect(Collectors.toMap(LineBaseData::getLineId, Function.identity()));

            List<FpyReportData> lineDetailList = excelReportMapper.getLineBaseInfo(lineIds);
            if (CollectionUtil.isNotEmpty(lineDetailList)) {
                for (FpyReportData fpyReportData : lineDetailList) {
                    if (integerLineBaseDataMap.containsKey(fpyReportData.getLineIndex())) {
                        BigDecimal bigDecimal = BigDecimal.valueOf(integerLineBaseDataMap.get(fpyReportData.getLineIndex()).getValue());
                        bigDecimal = bigDecimal.multiply(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP);
                        fpyReportData.setIntegrity(bigDecimal.toString());
                    } else {
                        fpyReportData.setIntegrity("暂无数据");
                    }
                }
            }


            Map<Integer, FpyReportData> integerFpyReportDataMap = lineDetailList.stream().collect(Collectors.toMap(FpyReportData::getLineIndex, Function.identity()));

            Example exampleOverLimit = new Example(OverLimit.class);
            exampleOverLimit.createCriteria().andIn("myIndex", lineIds);
            List<OverLimit> overLimitList = overLimitMapper.selectByExample(exampleOverLimit);
            Map<Long, OverLimit> overLimitMap = overLimitList.stream().collect(Collectors.toMap(OverLimit::getMyIndex, Function.identity()));


            //开始计算
            for (Map<String, BigDecimal> map : limitRateCalDTOList) {
                Long lineIndex = map.get("MYINDEX").longValue();
                Map<String, Object> mapOverLimit = new HashMap<>();
                try {
                    BeanUtils.describe(overLimitMap.get(lineIndex)).forEach(mapOverLimit::put);
                } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                    e.printStackTrace();
                }

                //获取平均值的最大值
                Map<String, BigDecimal> iM = mapMap.get(lineIndex.intValue());

                FpyTagContent fpyTagContent = calAllTag(map, mapOverLimit,iM);

                FpyReportData fpyReportData = new FpyReportData();
                if (integerFpyReportDataMap.containsKey(lineIndex.intValue())) {
                    FpyReportData fpyReport = integerFpyReportDataMap.get(lineIndex.intValue());
                    BeanUtil.copyProperties(fpyReport, fpyReportData);
                    fpyReportData.setHarmDes(fpyTagContent.getPassFlag());
                    fpyReportData.setPowerDes(fpyTagContent.getContent());
                    result.add(fpyReportData);
                }


            }
        }

        return result;
    }


    /**
     * 其他指标计算
     */
    private FpyTagContent calAllTag(Map<String, BigDecimal> map, Map<String, Object> mapOverLimit,Map<String, BigDecimal> iMap) {
        StrBuilder content = new StrBuilder();
        BigDecimal alltime = map.get("ALLTIME");
        BigDecimal flicketAllTime = map.get("FLICKET_ALLTIME");
        //频率偏差
        BigDecimal freq = map.get("FREQ_DEV_OVERTIME");
        if (freq.intValue() > 0) {
            //BigDecimal freqLimit = new BigDecimal(mapOverLimit.get("freqDev").toString());
            BigDecimal freqRate = alltime.subtract(freq).divide(alltime, 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
            content.append("频率偏差合格率").append(String.valueOf(freqRate.floatValue())).append("%;");
        }

        //电压偏差
        BigDecimal voltageDev = map.get("VOLTAGE_DEV_OVERTIME");
        if (voltageDev.intValue() > 0) {
            //BigDecimal voltageDevLimit = new BigDecimal(mapOverLimit.get("voltageDev").toString());
            BigDecimal voltageDevRate = alltime.subtract(voltageDev).divide(alltime, 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
            content.append("电压偏差合格率").append(String.valueOf(voltageDevRate.floatValue())).append("%;");
        }

        //三项不平衡
        BigDecimal ubalance = map.get("UBALANCE_OVERTIME");
        if (ubalance.intValue() > 0) {
           // BigDecimal ubalanceLimit = new BigDecimal(mapOverLimit.get("ubalance").toString());
            BigDecimal ubalanceRate = alltime.subtract(ubalance).divide(alltime, 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
            content.append("三相电压不平衡合格率").append(String.valueOf(ubalanceRate.floatValue())).append("%;");
        }

        //闪变
        BigDecimal flickOver = map.get("FLICKER_OVERTIME");
        if (flickOver.intValue() > 0) {
            //BigDecimal flickOverLimit = new BigDecimal(mapOverLimit.get("flicker").toString());
            BigDecimal flickOverRate = flicketAllTime.subtract(flickOver).divide(flicketAllTime, 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
            content.append("长时闪变合格率").append(String.valueOf(flickOverRate.floatValue())).append("%;");
        }

        //电压畸变
        BigDecimal uab = map.get("UABERRANCE_OVERTIME");
        BigDecimal uabRate = alltime.subtract(uab).divide(alltime, 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
        if (uabRate.floatValue() < 95) {
            //BigDecimal uabLimit = new BigDecimal(mapOverLimit.get("flicker").toString());
            content.append("电压总畸变率").append(String.valueOf(uabRate.floatValue())).append("%;");
        }

        //计算组装谐波含电压有率
        int flagV = 0;
        for (int i = 2; i < 26; i++) {
            BigDecimal v = map.get("UHARM_" + i + "_OVERTIME");
            BigDecimal hegeRate = alltime.subtract(v).divide(alltime, 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));

            if (hegeRate.floatValue() < 95) {
                //BigDecimal overLimit = new BigDecimal(mapOverLimit.get("uharm_" + i).toString());
                content.append(String.valueOf(i)).append("次谐波电压含有率合格率").append(String.valueOf(hegeRate.floatValue())).append("%;");
                flagV++;
            }
        }


        //计算组装谐波电流幅值
        int flagI = 0;
        for (int i = 2; i < 26; i++) {

            String key = "IHARM_" + i + "_OVERTIME";
            BigDecimal ih = map.get(key);
            BigDecimal hegeRate = alltime.subtract(ih).divide(alltime, 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));

            if (hegeRate.floatValue()<95) {
                BigDecimal maxI = iMap.get(key);
                BigDecimal overLimit = new BigDecimal(mapOverLimit.get("iharm_" + i).toString());
                content.append(String.valueOf(i)).append("次谐波电流合格率").append(String.valueOf(hegeRate.floatValue())).append("%,限值为").append(String.valueOf(overLimit.floatValue())).append("A," + "最大值为").append(String.valueOf(maxI)).append("A;");
                flagI++;
            }
        }
        FpyTagContent fpyTagContent = new FpyTagContent();
        if(flagV==0 && flagI==0){
            fpyTagContent.setPassFlag(EnumPass.PASS.getDescribe());
        }else if(flagV>0 && flagI==0){
            fpyTagContent.setPassFlag("谐波电压");
        }else if(flagV==0 && flagI>0){
            fpyTagContent.setPassFlag("谐波电流");
        }else {
            fpyTagContent.setPassFlag("谐波电压;谐波电流");
        }

        if(StrUtil.isBlank(content)){
            fpyTagContent.setContent("合格;");
        }else {
            fpyTagContent.setContent(content.toString());
        }
        return fpyTagContent;
    }


}
