package com.njcn.harmonic.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.njcn.common.config.GeneralInfo;
import com.njcn.device.pq.api.GeneralDeviceInfoClient;
import com.njcn.device.pq.api.LineFeignClient;
import com.njcn.device.pq.pojo.dto.GeneralDeviceDTO;
import com.njcn.device.pq.pojo.dto.OverLimitLineDTO;
import com.njcn.device.pq.pojo.dto.PollutionParamDTO;
import com.njcn.device.pq.pojo.dto.WarningSubstationDTO;
import com.njcn.event.api.EventDetailFeignClient;
import com.njcn.event.pojo.vo.GeneralVO;
import com.njcn.harmonic.constant.Param;
import com.njcn.harmonic.mapper.RStatLimitTargetMapper;
import com.njcn.harmonic.pojo.excel.area.AreaExcel;
import com.njcn.harmonic.pojo.excel.monitor.ITimes;
import com.njcn.harmonic.pojo.excel.monitor.MonitorExcel;
import com.njcn.harmonic.pojo.excel.monitor.OverLimitDays;
import com.njcn.harmonic.pojo.excel.monitor.UTimes;
import com.njcn.harmonic.pojo.excel.substation.SubstationExcel;
import com.njcn.harmonic.pojo.po.day.RStatLimitRateDPO;
import com.njcn.harmonic.pojo.po.day.RStatLimitTargetDPO;
import com.njcn.harmonic.pojo.vo.MonitorOverLimitVO;
import com.njcn.harmonic.pojo.vo.OverAreaLimitVO;
import com.njcn.harmonic.pojo.vo.OverAreaVO;
import com.njcn.harmonic.pojo.vo.WarningSubstationVO;
import com.njcn.harmonic.rstatlimitrate.mapper.RStatLimitRateDMapper;
import com.njcn.harmonic.service.IAnalyzeService;
import com.njcn.poi.excel.ExcelUtil;
import com.njcn.supervision.api.UserLedgerFeignClient;
import com.njcn.supervision.pojo.param.user.UserReportParam;
import com.njcn.supervision.pojo.vo.user.UserLedgerVO;
import com.njcn.system.api.DicDataFeignClient;
import com.njcn.system.enums.DicDataEnum;
import com.njcn.system.enums.DicDataTypeEnum;
import com.njcn.system.pojo.po.DictData;
import com.njcn.web.utils.RequestUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 类的介绍：
 *
 * @author xuyang
 * @version 1.0.0
 * @createTime 2022/4/29 14:48
 */
@Slf4j
@Service
@AllArgsConstructor
public class AnalyzeServiceImpl implements IAnalyzeService {

    private final GeneralDeviceInfoClient generalDeviceInfoClient;

    private final GeneralInfo generalInfo;

    private final HarmonicServiceImpl harmonicService;

    private final LineFeignClient lineFeignClient;

    private final RStatLimitRateDMapper rateDMapper;

    private final RStatLimitTargetMapper targetMapper;
    private final EventDetailFeignClient eventDetailFeignClient;
    private final DicDataFeignClient dicDataFeignClient;

    private final UserLedgerFeignClient userLedgerFeignClient;

    @Override
    public Page<OverAreaLimitVO> getAreaData(OverAreaVO param) {
        Page<OverAreaLimitVO> page = new Page<>();
        page.setSize(param.getPageSize());
        page.setCurrent(param.getPageNum());
        List<OverAreaLimitVO> list = new ArrayList<>();
        param.setServerName(generalInfo.getMicroServiceName());
        List<GeneralDeviceDTO> deptList = generalDeviceInfoClient.getPracticalRunDeviceInfo(param).getData();
        if (!CollectionUtils.isEmpty(deptList)) {
            page.setTotal(deptList.size());
            int pages = (int) Math.ceil(deptList.size() * 1.0 / param.getPageSize());
            page.setPages(pages);
            List<List<GeneralDeviceDTO>> pageList = Lists.partition(deptList, param.getPageSize());
            List<GeneralDeviceDTO> temList = pageList.get(param.getPageNum() - 1);
            temList.forEach(item -> {
                OverAreaLimitVO overAreaLimitVO = new OverAreaLimitVO();
                if (!CollectionUtils.isEmpty(item.getLineIndexes())) {
                    List<RStatLimitTargetDPO> limitTargetList = harmonicService.getLimitTarget(item.getLineIndexes(), param.getSearchBeginTime(), param.getSearchEndTime());
                    overAreaLimitVO = handleAreaData(limitTargetList, item.getLineIndexes(), param);
                }
                overAreaLimitVO.setName(item.getName());
                list.add(overAreaLimitVO);
            });
            if (!CollectionUtils.isEmpty(list)) {
                List<OverAreaLimitVO> recordList = new ArrayList<>();
                //默认 根据在线监测点个数 倒叙排序
                recordList = list.stream().sorted(Comparator.comparing(OverAreaLimitVO::getOnlineMonitorNumber).reversed().thenComparing(OverAreaLimitVO::getName)).collect(Collectors.toList());
                page.setRecords(recordList);
                return page;
            }
        }
        return page;
    }

    @Override
    @SuppressWarnings("unchecked")
    public Page<WarningSubstationVO> getWarningSubstation(OverAreaVO param) {
        //获取暂态统计指标
        List<DictData> eventStatis = dicDataFeignClient.getDicDataByTypeCode(
                DicDataTypeEnum.EVENT_STATIS.getCode()).getData();

        Page<WarningSubstationVO> page = new Page<>();
        page.setSize(param.getPageSize());
        page.setCurrent(param.getPageNum());
        List<String> line = new ArrayList<>(), subInfo = new ArrayList<>();
        List<WarningSubstationDTO> substationDTOList = new ArrayList<>();
        Map<String, List<RStatLimitRateDPO>> map = new HashMap<>();
        Map<String, GeneralVO> map2 = new HashMap<>();
        param.setServerName(generalInfo.getMicroServiceName());
        List<WarningSubstationVO> list = new ArrayList<>();
        List<GeneralDeviceDTO> subList = generalDeviceInfoClient.getPracticalRunDeviceInfoAsSubstation(param).getData();
        if (!CollectionUtils.isEmpty(subList)) {
            page.setTotal(subList.size());
            int pages = (int) Math.ceil(subList.size() * 1.0 / param.getPageSize());
            page.setPages(pages);
            List<List<GeneralDeviceDTO>> pageList = Lists.partition(subList, param.getPageSize());
            List<GeneralDeviceDTO> temList = pageList.get(param.getPageNum() - 1);
            temList.forEach(item -> {
                line.addAll(item.getLineIndexes());
                subInfo.add(item.getIndex());
            });
            if (!CollectionUtils.isEmpty(line)) {
                substationDTOList = lineFeignClient.getWarningSub(subInfo).getData();
                List<RStatLimitRateDPO> limitRateList = (List<RStatLimitRateDPO>) getAllData(line, param.getSearchBeginTime(), param.getSearchEndTime(), Param.LIMIT_RATE);
                if (!CollectionUtils.isEmpty(limitRateList)) {
                    map = limitRateList.stream().collect(Collectors.groupingBy(RStatLimitRateDPO::getLineId));
                }
                List<GeneralVO> eventDetailList = getEventDetail(line, param.getSearchBeginTime(), param.getSearchEndTime(), eventStatis);
                if (!CollectionUtils.isEmpty(eventDetailList)) {
                    map2 = eventDetailList.stream().collect(Collectors.toMap(GeneralVO::getId, Function.identity()));
                }
            }
            for (GeneralDeviceDTO item : temList) {
                int onlineMonitorCount = 0, alertMonitorCount = 0, alertCount = 0, freqCount = 0, voltageCount = 0, ubalanceCount = 0, flickerCount = 0, iNegCount = 0, uharmCount = 0, iharmCount = 0, inuharmCount = 0;
                int freqCounts = 0, voltageCounts = 0, uharmCounts = 0, iharmCounts = 0, ubalanceCounts = 0, flickerCounts = 0, inuharmCounts = 0, iNegCounts = 0;
                int eventUp = 0, eventDown = 0, eventInterrupt = 0, eventUps = 0, eventDowns = 0, eventInterrupts = 0;
                WarningSubstationVO warningSubstationVO = new WarningSubstationVO();
                //电站id
                warningSubstationVO.setId(item.getIndex());
                //电站名称
                warningSubstationVO.setPlantName(item.getName());
                List<String> lineList = item.getLineIndexes();
                if (!CollectionUtils.isEmpty(lineList)) {
                    for (String item2 : lineList) {
                        //谐波统计
                        if (!CollectionUtils.isEmpty(map.get(item2))) {
                            RStatLimitRateDPO limitRate = map.get(item2).get(0);
                            if (!Objects.isNull(limitRate)) {
                                onlineMonitorCount++;
                                if (limitRate.getFreqDevOvertime() > 0 || limitRate.getVoltageDevOvertime() > 0 || limitRate.getUbalanceOvertime() > 0 || limitRate.getFlickerOvertime() > 0 || limitRate.getINegOvertime() > 0 || limitRate.getUharm2Overtime() > 0 || limitRate.getIharm2Overtime() > 0 || limitRate.getInuharm1Overtime() > 0) {
                                    alertMonitorCount++;
                                }
                                if (limitRate.getFreqDevOvertime() > 0) {
                                    freqCount++;
                                    freqCounts = freqCounts + limitRate.getFreqDevOvertime();
                                }
                                if (limitRate.getVoltageDevOvertime() > 0) {
                                    voltageCount++;
                                    voltageCounts = voltageCounts + limitRate.getVoltageDevOvertime();
                                }
                                if (limitRate.getUharm2Overtime() > 0) {
                                    uharmCount++;
                                    uharmCounts = uharmCounts + limitRate.getUharm2Overtime();
                                }
                                if (limitRate.getIharm2Overtime() > 0) {
                                    iharmCount++;
                                    iharmCounts = iharmCounts + limitRate.getIharm2Overtime();
                                }
                                if (limitRate.getUbalanceOvertime() > 0) {
                                    ubalanceCount++;
                                    ubalanceCounts = ubalanceCounts + limitRate.getUbalanceOvertime();
                                }
                                if (limitRate.getFlickerOvertime() > 0) {
                                    flickerCount++;
                                    flickerCounts = flickerCounts + limitRate.getFlickerOvertime();
                                }
                                if (limitRate.getInuharm1Overtime() > 0) {
                                    inuharmCount++;
                                    inuharmCounts = inuharmCounts + limitRate.getInuharm1Overtime();
                                }
                                if (limitRate.getINegOvertime() > 0) {
                                    iNegCount++;
                                    iNegCounts = iNegCounts + limitRate.getINegOvertime();
                                }
                                alertCount = limitRate.getFreqDevOvertime() + limitRate.getVoltageDevOvertime() + limitRate.getUbalanceOvertime() + limitRate.getFlickerOvertime() + limitRate.getINegOvertime() + limitRate.getUharm2Overtime() + limitRate.getIharm2Overtime() + limitRate.getInuharm1Overtime();
                            }
                        }
                        //暂降统计
                        if (ObjectUtil.isNotNull(map2.get(item2))) {
                            GeneralVO eventDetailList = map2.get(item2);
                            if (ObjectUtil.isNotNull(eventDetailList)) {
                                //电压暂降
                                eventDowns += eventDetailList.getSagsCount();
                                //电压暂升
                                eventUps += eventDetailList.getUpCount();
                                //电压暂升
                                eventInterrupts += eventDetailList.getBreakCount();
                            }
                        }
                        if (eventDowns > 0) {
                            eventDown++;
                        }
                        if (eventUps > 0) {
                            eventUp++;
                        }
                        if (eventInterrupts > 0) {
                            eventInterrupt++;
                        }
                    }
                }
                //在线监测点数量(个)
                warningSubstationVO.setOnlineMonitorCounts(onlineMonitorCount);
                if (onlineMonitorCount != 0) {
                    //告警监测点数量(个)
                    warningSubstationVO.setAlertMonitorCounts(alertMonitorCount);
                    //告警次数
                    warningSubstationVO.setAlertCounts(alertCount);
                    //告警频次(次/点)
                    warningSubstationVO.setAlertAlarmFrequency(alertMonitorCount == 0 ? 0 : BigDecimal.valueOf(alertCount * 1.0 / alertMonitorCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
                    //频率偏差
                    warningSubstationVO.setFrequencyDeviation(freqCount == 0 ? 0 : BigDecimal.valueOf(freqCounts * 1.0 / freqCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
                    //电压偏差
                    warningSubstationVO.setVoltageDeviation(voltageCount == 0 ? 0 : BigDecimal.valueOf(voltageCounts * 1.0 / voltageCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
                    //谐波电压
                    warningSubstationVO.setHarmonicVoltage(uharmCount == 0 ? 0 : BigDecimal.valueOf(uharmCounts * 1.0 / uharmCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
                    //谐波电流
                    warningSubstationVO.setHarmonicCurrent(iharmCount == 0 ? 0 : BigDecimal.valueOf(iharmCounts * 1.0 / iharmCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
                    //三相电压不平衡
                    warningSubstationVO.setThreePhaseVoltageUnbalance(ubalanceCount == 0 ? 0 : BigDecimal.valueOf(ubalanceCounts * 1.0 / ubalanceCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
                    //闪变
                    warningSubstationVO.setFlicker(flickerCount == 0 ? 0 : BigDecimal.valueOf(flickerCounts * 1.0 / flickerCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
                    //间谐波电压
                    warningSubstationVO.setInterHarmonic(inuharmCount == 0 ? 0 : BigDecimal.valueOf(inuharmCounts * 1.0 / inuharmCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
                    //负序电流
                    warningSubstationVO.setNegative(iNegCount == 0 ? 0 : BigDecimal.valueOf(iNegCounts * 1.0 / iNegCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
                    //电压暂降
                    warningSubstationVO.setVoltageDip(eventDown == 0 ? 0 : BigDecimal.valueOf(eventDowns * 1.0 / eventDown).setScale(2, RoundingMode.HALF_UP).doubleValue());
                    //电压暂升
                    warningSubstationVO.setVoltageSwell(eventUp == 0 ? 0 : BigDecimal.valueOf(eventUps * 1.0 / eventUp).setScale(2, RoundingMode.HALF_UP).doubleValue());
                    //短时中断
                    warningSubstationVO.setShortInterruption(eventInterrupt == 0 ? 0 : BigDecimal.valueOf(eventInterrupts * 1.0 / eventInterrupt).setScale(2, RoundingMode.HALF_UP).doubleValue());
                }
                list.add(warningSubstationVO);
            }
        }
        if (!CollectionUtils.isEmpty(list)) {
            for (WarningSubstationVO item1 : list) {
                for (WarningSubstationDTO item2 : substationDTOList) {
                    if (Objects.equals(item1.getId(), item2.getId())) {
                        item1.setProvinceCompany(item2.getProvince());
                        item1.setCityCompany(item2.getCity());
                        item1.setPlantVoltageLevel(item2.getScale());
                    }
                }
            }
            List<WarningSubstationVO> recordList = new ArrayList<>();
            //默认 在线监测点数量 倒叙排序
            recordList = list.stream().sorted(Comparator.comparing(WarningSubstationVO::getOnlineMonitorCounts).reversed().thenComparing(WarningSubstationVO::getPlantName)).collect(Collectors.toList());
            page.setRecords(recordList);
            return page;
        }
        return page;
    }

    @Override
    public Page<MonitorOverLimitVO> monitorOverLimitVO(OverAreaVO param) {
        Page<MonitorOverLimitVO> page = new Page<>();
        page.setSize(param.getPageSize());
        page.setCurrent(param.getPageNum());
        List<MonitorOverLimitVO> result = new ArrayList<>();
        List<String> lineList = new ArrayList<>();
        List<GeneralDeviceDTO> deptList = generalDeviceInfoClient.getPracticalRunDeviceInfo(param).getData();
        if (!CollectionUtils.isEmpty(deptList)) {
            deptList.forEach(item -> {
                lineList.addAll(item.getLineIndexes());
            });
        }
        if (CollectionUtil.isNotEmpty(lineList)) {
            page = targetMapper.getSumLimitTargetPage(page, lineList, DateUtil.beginOfDay(DateUtil.parse(param.getSearchBeginTime())),
                    DateUtil.endOfDay(DateUtil.parse(param.getSearchEndTime())));
            List<MonitorOverLimitVO> pageRecords = page.getRecords();
            if (CollectionUtils.isEmpty(pageRecords)) {
                return page;
            }
            Map<String, List<MonitorOverLimitVO>> monMap = pageRecords.stream().collect(Collectors.groupingBy(MonitorOverLimitVO::getId));
            ArrayList<String> list = new ArrayList<>();
            list.addAll(monMap.keySet());
            PollutionParamDTO pollutionParamDTO = new PollutionParamDTO();
            pollutionParamDTO.setLineList(list);
            List<OverLimitLineDTO> overLimitLineList = lineFeignClient.getOverLimitLineInfo(pollutionParamDTO).getData();
            List<RStatLimitTargetDPO> rStatLimitTargetDPOS = targetMapper.selectList(new QueryWrapper<RStatLimitTargetDPO>()
                    .in("r_stat_limit_target_d.my_index", list).between("r_stat_limit_target_d.time_id", DateUtil.beginOfDay(DateUtil.parse(param.getSearchBeginTime())),
                            DateUtil.endOfDay(DateUtil.parse(param.getSearchEndTime()))));
            Map<String, List<RStatLimitTargetDPO>> rsMap = rStatLimitTargetDPOS.stream().collect(Collectors.groupingBy(RStatLimitTargetDPO::getLineId));


            List<UserLedgerVO> userLedgerVOList = userLedgerFeignClient.selectUserList(new UserReportParam()).getData();
            Map<String,UserLedgerVO> userLedgerVOMap = userLedgerVOList.stream().collect(Collectors.toMap(UserLedgerVO::getId,Function.identity()));

            for (OverLimitLineDTO vo : overLimitLineList) {
                MonitorOverLimitVO monitorOverLimitVO = new MonitorOverLimitVO();
                BeanUtil.copyProperties(vo, monitorOverLimitVO);
                MonitorOverLimitVO source = monMap.get(vo.getId()).get(0);
                UserLedgerVO userLedgerVO = userLedgerVOMap.getOrDefault(vo.getObjId(),null);
                monitorOverLimitVO.setLineObjectName(Objects.nonNull(userLedgerVO)?userLedgerVO.getProjectName():"/");
                monitorOverLimitVO.setOverDay(source.getOverDay());
                monitorOverLimitVO.setVolDevOverDay(source.getVolDevOverDay());
                monitorOverLimitVO.setFreqOverDay(source.getFreqOverDay());
                monitorOverLimitVO.setFlickerOverDay(source.getFlickerOverDay());
                monitorOverLimitVO.setNegativeOverDay(source.getNegativeOverDay());
                monitorOverLimitVO.setThreeUnbalance(source.getThreeUnbalance());
                monitorOverLimitVO.setVolDisOverDay(source.getVolDisOverDay());
                monitorOverLimitVO.setOverVolThreeTimes(source.getOverVolThreeTimes());
                monitorOverLimitVO.setOverVolFiveTimes(source.getOverVolFiveTimes());
                monitorOverLimitVO.setOverVolSevenTimes(source.getOverVolSevenTimes());
                monitorOverLimitVO.setOverVolElevenTimes(source.getOverVolElevenTimes());
                monitorOverLimitVO.setOverVolThirteenTimes(source.getOverVolThirteenTimes());
                monitorOverLimitVO.setOverVolTwentyThreeTimes(source.getOverVolTwentyThreeTimes());
                monitorOverLimitVO.setOverVolTwentyFiveTimes(source.getOverVolTwentyFiveTimes());
                monitorOverLimitVO.setOverVolOtherTimes(source.getOverVolOtherTimes());
                monitorOverLimitVO.setOverCurThreeTimes(source.getOverCurThreeTimes());
                monitorOverLimitVO.setOverCurFiveTimes(source.getOverCurFiveTimes());
                monitorOverLimitVO.setOverCurSevenTimes(source.getOverCurSevenTimes());
                monitorOverLimitVO.setOverCurElevenTimes(source.getOverCurElevenTimes());
                monitorOverLimitVO.setOverCurThirteenTimes(source.getOverCurThirteenTimes());
                monitorOverLimitVO.setOverCurTwentyThreeTimes(source.getOverCurTwentyThreeTimes());
                monitorOverLimitVO.setOverCurTwentyFiveTimes(source.getOverCurTwentyFiveTimes());
                monitorOverLimitVO.setOverCurOtherTimes(source.getOverCurOtherTimes());
                List<RStatLimitTargetDPO> limitRateDPOS = rsMap.get(vo.getId());
                // 谐波电压含有率超标天数
                long volContainOverDay = limitRateDPOS.stream().filter(t -> filterNotQualifiedUharmData(t)).count();
                // 谐波电流超标天数
                long harmCurOverDay = limitRateDPOS.stream().filter(t -> filterNotQualifiedIharmData(t)).count();
                // 间谐波电压含有率超标天数
                long intHarmOverDay = limitRateDPOS.stream().filter(t -> filterNotQualifiedInuharmData(t)).count();
                // 谐波电压超标天数
                long harmVolOverDay = limitRateDPOS.stream().filter(t -> filterNotQualifiedHarmVolData(t)).count();
                monitorOverLimitVO.setHarmVolOverDay((int) harmVolOverDay);
                monitorOverLimitVO.setVolContainOverDay((int) volContainOverDay);
                monitorOverLimitVO.setHarmCurOverDay((int) harmCurOverDay);
                monitorOverLimitVO.setIntHarmOverDay((int) intHarmOverDay);
                result.add(monitorOverLimitVO);
            }

        }
        if (!CollectionUtils.isEmpty(result)) {
            //默认 根据在线监测点个数 倒叙排序
            List<MonitorOverLimitVO> recordList = result.stream().sorted(Comparator.comparing(MonitorOverLimitVO::getOverDay).reversed()).collect(Collectors.toList());
            page.setRecords(recordList);
            return page;
        }
        return page;
    }

    private boolean filterNotQualifiedHarmVolData(RStatLimitTargetDPO t) {
        // 电压畸变率+谐波电压含有率（2-25次）
        int i = t.getUaberranceOvertime() + t.getUharm2Overtime() + t.getUharm3Overtime() + t.getUharm4Overtime() + t.getUharm5Overtime() + t.getUharm6Overtime() + t.getUharm7Overtime() + t.getUharm8Overtime() + t.getUharm9Overtime() + t.getUharm10Overtime() + t.getUharm11Overtime() + t.getUharm12Overtime() + t.getUharm13Overtime() + t.getUharm14Overtime() + t.getUharm15Overtime() + t.getUharm16Overtime() + t.getUharm17Overtime() + t.getUharm18Overtime() + t.getUharm19Overtime() + t.getUharm20Overtime() + t.getUharm21Overtime() + t.getUharm22Overtime() + t.getUharm23Overtime() + t.getUharm24Overtime() + t.getUharm25Overtime();
        if (i > 0) {
            return true;
        }
        return false;
    }

    private boolean filterNotQualifiedInuharmData(RStatLimitTargetDPO t) {
        int i = t.getInuharm1Overtime() + t.getInuharm2Overtime() + t.getInuharm3Overtime() + t.getInuharm4Overtime() + t.getInuharm5Overtime() + t.getInuharm6Overtime() + t.getInuharm7Overtime() + t.getInuharm8Overtime() + t.getInuharm9Overtime() + t.getInuharm10Overtime() + t.getInuharm11Overtime() + t.getInuharm12Overtime() + t.getInuharm13Overtime() + t.getInuharm14Overtime() + t.getInuharm15Overtime() + t.getInuharm16Overtime();
        if (i > 0) {
            return true;
        }
        return false;
    }

    private boolean filterNotQualifiedIharmData(RStatLimitTargetDPO t) {
        int i = t.getIharm2Overtime() + t.getIharm3Overtime() + t.getIharm4Overtime() + t.getIharm5Overtime() + t.getIharm6Overtime() + t.getIharm7Overtime() + t.getIharm8Overtime() + t.getIharm9Overtime() + t.getIharm10Overtime() + t.getIharm11Overtime() + t.getIharm12Overtime() + t.getIharm13Overtime() + t.getIharm14Overtime() + t.getIharm15Overtime() + t.getIharm16Overtime() + t.getIharm17Overtime() + t.getIharm18Overtime() + t.getIharm19Overtime() + t.getIharm20Overtime() + t.getIharm21Overtime() + t.getIharm22Overtime() + t.getIharm23Overtime() + t.getIharm24Overtime() + t.getIharm25Overtime();
        if (i > 0) {
            return true;
        }
        return false;
    }

    private boolean filterNotQualifiedUharmData(RStatLimitTargetDPO t) {
        if (t.getUharm2Overtime() != 0 || t.getUharm3Overtime() != 0 || t.getUharm4Overtime() != 0 || t.getUharm5Overtime() != 0 || t.getUharm6Overtime() != 0 || t.getUharm7Overtime() != 0 || t.getUharm8Overtime() != 0 || t.getUharm9Overtime() != 0 || t.getUharm10Overtime() != 0 || t.getUharm11Overtime() != 0 || t.getUharm12Overtime() != 0 || t.getUharm13Overtime() != 0 || t.getUharm14Overtime() != 0 || t.getUharm15Overtime() != 0 || t.getUharm16Overtime() != 0 || t.getUharm17Overtime() != 0 || t.getUharm18Overtime() != 0 || t.getUharm19Overtime() != 0 || t.getUharm20Overtime() != 0 || t.getUharm21Overtime() != 0 || t.getUharm22Overtime() != 0 || t.getUharm23Overtime() != 0 || t.getUharm24Overtime() != 0 || t.getUharm25Overtime() != 0) {
            return true;
        }
        return false;
    }

    @Override
    public String exportArea(OverAreaVO param, String methodDescribe) {
        List<AreaExcel> result = new ArrayList<>();
        String fileName = methodDescribe + CharUtil.UNDERLINE + param.getSearchBeginTime() + CharUtil.DASHED + param.getSearchEndTime() + CharUtil.UNDERLINE + param.getStatisticalType().getName() + ".xlsx";
        String targetDir = generalInfo.getBusinessTempPath() + File.separator + RequestUtil.getUserIndex();
        log.error("文件路径" + targetDir);
        log.error("文件名" + fileName);
        File excel = new File(targetDir, fileName);
        List<OverAreaLimitVO> list = getAreaData(param).getRecords();
        if (!CollectionUtil.isEmpty(list)) {
            list.forEach(item -> {
                AreaExcel areaExcel = new AreaExcel();
                BeanUtil.copyProperties(item, areaExcel);
                result.add(areaExcel);
            });
        }
        ExcelUtil.exportExcelWithTargetFile(excel, param.getStatisticalType().getName(), methodDescribe, AreaExcel.class, result);
        return FileUtil.getAbsolutePath(excel);
    }

    @Override
    public String exportSubstation(OverAreaVO param, String methodDescribe) {
        List<SubstationExcel> result = new ArrayList<>();
        String fileName = methodDescribe + CharUtil.UNDERLINE + param.getSearchBeginTime() + CharUtil.DASHED + param.getSearchEndTime() + CharUtil.UNDERLINE + param.getStatisticalType().getName() + ".xlsx";
        String targetDir = generalInfo.getBusinessTempPath() + File.separator + RequestUtil.getUserIndex();
        log.error("文件路径" + targetDir);
        log.error("文件名" + fileName);
        File excel = new File(targetDir, fileName);
        List<WarningSubstationVO> list = getWarningSubstation(param).getRecords();
        if (!CollectionUtil.isEmpty(list)) {
            list.forEach(item -> {
                SubstationExcel substationExcel = new SubstationExcel();
                BeanUtil.copyProperties(item, substationExcel);
                result.add(substationExcel);
            });
        }
        ExcelUtil.exportExcelWithTargetFile(excel, param.getStatisticalType().getName(), methodDescribe, SubstationExcel.class, result);
        return FileUtil.getAbsolutePath(excel);
    }

    @Override
    public String exportMonitor(OverAreaVO param, String methodDescribe) {
        List<MonitorExcel> result = new ArrayList<>();
        String fileName = methodDescribe + CharUtil.UNDERLINE + param.getSearchBeginTime() + CharUtil.DASHED + param.getSearchEndTime() + CharUtil.UNDERLINE + param.getStatisticalType().getName() + ".xlsx";
        String targetDir = generalInfo.getBusinessTempPath() + File.separator + RequestUtil.getUserIndex();
        log.error("文件路径" + targetDir);
        log.error("文件名" + fileName);
        File excel = new File(targetDir, fileName);
        List<MonitorOverLimitVO> list = monitorOverLimitVO(param).getRecords();
        if (!CollectionUtil.isEmpty(list)) {
            list.forEach(item -> {
                MonitorExcel monitorExcel = new MonitorExcel();
                BeanUtil.copyProperties(item, monitorExcel);

                OverLimitDays overLimitDays = new OverLimitDays();
                List<UTimes> list1 = new ArrayList<>();
                UTimes uTimes = new UTimes();
                BeanUtil.copyProperties(item, uTimes);
                list1.add(uTimes);
                overLimitDays.setUTimes(list1);

                List<ITimes> list2 = new ArrayList<>();
                ITimes iTimes = new ITimes();
                BeanUtil.copyProperties(item, iTimes);
                list2.add(iTimes);
                overLimitDays.setITimes(list2);

                List<OverLimitDays> list3 = new ArrayList<>();
                BeanUtil.copyProperties(item, overLimitDays);
                list3.add(overLimitDays);
                monitorExcel.setOverLimitDays(list3);
                result.add(monitorExcel);
            });
        }
        ExcelUtil.exportExcelWithTargetFile(excel, param.getStatisticalType().getName(), methodDescribe, MonitorExcel.class, result);
        return FileUtil.getAbsolutePath(excel);
    }


    /**
     * 功能描述: 处理区域(变电站)在线监测点数、超标监测点数、平均超标天数、占比
     *
     * @param list 集合
     *             type 类型
     * @return
     * @author xy
     * @date 2022/2/25 15:05
     */
    @SuppressWarnings("unchecked")
    public OverAreaLimitVO handleAreaData(List<RStatLimitTargetDPO> list, List<String> line, OverAreaVO param) {
        int onlineCount = 0, overLineCount = 0, freqCount = 0, voltageCount = 0, ubalanceCount = 0, flickerCount = 0, iNegCount = 0, uharmCount = 0, iharmCount = 0, inuharmCount = 0;
        int freqOverDay = 0, voltageOverDay = 0, ubalanceOverDay = 0, flickerOverDay = 0, iNegOverDay = 0, uharmOverDay = 0, iharmOverDay = 0, inuharmOverDay = 0;
        OverAreaLimitVO overAreaLimitVO = new OverAreaLimitVO();
        if (!CollectionUtils.isEmpty(list)) {
            List<RStatLimitTargetDPO> data = (List<RStatLimitTargetDPO>) getAllData(line, param.getSearchBeginTime(), param.getSearchEndTime(), Param.LIMIT_TARGET);
            if (!CollectionUtils.isEmpty(data)) {
                onlineCount = data.size();
                //在线监测点个数
                overAreaLimitVO.setOnlineMonitorNumber(onlineCount);
                for (RStatLimitTargetDPO item : data) {
                    if (item.getFreqDevOvertime() > 0 || item.getVoltageDevOvertime() > 0 || item.getUbalanceOvertime() > 0 || item.getFlickerOvertime() > 0 || item.getINegOvertime() > 0 || item.getUharm2Overtime() > 0 || item.getIharm2Overtime() > 0 || item.getInuharm1Overtime() > 0) {
                        overLineCount++;
                    }
                    if (item.getFreqDevOvertime() > 0) {
                        freqCount++;
                    }
                    if (item.getVoltageDevOvertime() > 0) {
                        voltageCount++;
                    }
                    if (item.getUbalanceOvertime() > 0) {
                        ubalanceCount++;
                    }
                    if (item.getFlickerOvertime() > 0) {
                        flickerCount++;
                    }
                    if (item.getINegOvertime() > 0) {
                        iNegCount++;
                    }
                    if (item.getUharm2Overtime() > 0) {
                        uharmCount++;
                    }
                    if (item.getIharm2Overtime() > 0) {
                        iharmCount++;
                    }
                    if (item.getInuharm1Overtime() > 0) {
                        inuharmCount++;
                    }
                }
                //超标监测点个数
                overAreaLimitVO.setOverLimitMonitorNumber(overLineCount);
                //超标监测点数占比
                overAreaLimitVO.setOverBiLi(BigDecimal.valueOf(overLineCount * 1.0 / data.size() * 100).setScale(2, RoundingMode.HALF_UP).doubleValue());
                //频率偏差
                overAreaLimitVO.setFrequencyMonitorNumber(freqCount);
                overAreaLimitVO.setFrequencyBiLi(BigDecimal.valueOf(freqCount * 1.0 / data.size() * 100).setScale(2, RoundingMode.HALF_UP).doubleValue());
                //电压偏差
                overAreaLimitVO.setVoltageMonitorNumber(voltageCount);
                overAreaLimitVO.setVoltageBiLi(BigDecimal.valueOf(voltageCount * 1.0 / data.size() * 100).setScale(2, RoundingMode.HALF_UP).doubleValue());
                //谐波电压
                overAreaLimitVO.setHarmonicVoltageMonitorNumber(uharmCount);
                overAreaLimitVO.setHarmonicVoltageBiLi(BigDecimal.valueOf(uharmCount * 1.0 / data.size() * 100).setScale(2, RoundingMode.HALF_UP).doubleValue());
                //谐波电流
                overAreaLimitVO.setHarmonicCurrentMonitorNumber(iharmCount);
                overAreaLimitVO.setHarmonicCurrentBiLi(BigDecimal.valueOf(iharmCount * 1.0 / data.size() * 100).setScale(2, RoundingMode.HALF_UP).doubleValue());
                //三相电压不平衡度
                overAreaLimitVO.setThreePhaseVoltageMonitorNumber(ubalanceCount);
                overAreaLimitVO.setThreePhaseVoltageBiLi(BigDecimal.valueOf(ubalanceCount * 1.0 / data.size() * 100).setScale(2, RoundingMode.HALF_UP).doubleValue());
                //闪变
                overAreaLimitVO.setFlickerMonitorNumber(flickerCount);
                overAreaLimitVO.setFlickerBiLi(BigDecimal.valueOf(flickerCount * 1.0 / data.size() * 100).setScale(2, RoundingMode.HALF_UP).doubleValue());
                //负序电流
                overAreaLimitVO.setNegativeMonitorNumber(iNegCount);
                overAreaLimitVO.setNegativeBiLi(BigDecimal.valueOf(iNegCount * 1.0 / data.size() * 100).setScale(2, RoundingMode.HALF_UP).doubleValue());
                //间谐波电压
                overAreaLimitVO.setInterHarmonicMonitorNumber(inuharmCount);
                overAreaLimitVO.setInterHarmonicBiLi(BigDecimal.valueOf(inuharmCount * 1.0 / data.size() * 100).setScale(2, RoundingMode.HALF_UP).doubleValue());
            }
        }
        Map<LocalDate, List<RStatLimitTargetDPO>> map = list.stream().collect(Collectors.groupingBy(RStatLimitTargetDPO::getTime));
        for (LocalDate key : map.keySet()) {
            List<RStatLimitTargetDPO> l = map.get(key);
            for (RStatLimitTargetDPO pojo : l) {
                if (pojo.getFreqDevOvertime() > 0) {
                    freqOverDay++;
                }
                if (pojo.getVoltageDevOvertime() > 0) {
                    voltageOverDay++;
                }
                if (pojo.getUbalanceOvertime() > 0) {
                    ubalanceOverDay++;
                }
                if (pojo.getFlickerOvertime() > 0) {
                    flickerOverDay++;
                }
                if (pojo.getINegOvertime() > 0) {
                    iNegOverDay++;
                }
                if (pojo.getUharm2Overtime() > 0) {
                    uharmOverDay++;
                }
                if (pojo.getIharm2Overtime() > 0) {
                    iharmOverDay++;
                }
                if (pojo.getInuharm2Overtime() > 0) {
                    inuharmOverDay++;
                }
            }
        }
        if (onlineCount != 0) {
            overAreaLimitVO.setFrequencyOverDayBiLi(freqCount == 0 ? 0.0 : BigDecimal.valueOf(freqOverDay * 1.0 / freqCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
            overAreaLimitVO.setVoltageOverDayBiLi(voltageCount == 0 ? 0.0 : BigDecimal.valueOf(voltageOverDay * 1.0 / voltageCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
            overAreaLimitVO.setThreePhaseVoltageOverDayBiLi(ubalanceCount == 0 ? 0.0 : BigDecimal.valueOf(ubalanceOverDay * 1.0 / ubalanceCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
            overAreaLimitVO.setFlickerOverDayBiLi(flickerCount == 0 ? 0.0 : BigDecimal.valueOf(flickerOverDay * 1.0 / flickerCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
            overAreaLimitVO.setNegativeOverDayBiLi(iNegCount == 0 ? 0.0 : BigDecimal.valueOf(iNegOverDay * 1.0 / iNegCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
            overAreaLimitVO.setHarmonicVoltageOverDayBiLi(uharmCount == 0 ? 0.0 : BigDecimal.valueOf(uharmOverDay * 1.0 / uharmCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
            overAreaLimitVO.setHarmonicCurrentOverDayBiLi(iharmCount == 0 ? 0.0 : BigDecimal.valueOf(iharmOverDay * 1.0 / iharmCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
            overAreaLimitVO.setInterHarmonicOverDayBiLi(inuharmCount == 0 ? 0.0 : BigDecimal.valueOf(inuharmOverDay * 1.0 / inuharmCount).setScale(2, RoundingMode.HALF_UP).doubleValue());
        }
        return overAreaLimitVO;
    }

    /**
     * 功能描述: 处理区域在线监测点数、超标监测点数
     *
     * @param list 集合
     * @return
     * @author xy
     * @date 2022/2/25 15:05
     */
    private List<?> getAllData(List<String> list, String startTime, String endTime, String databaseName) {
        List<?> result = new ArrayList<>();
        switch (databaseName) {
            case Param.LIMIT_TARGET:
                result = targetMapper.getSumTargetList(list, startTime, endTime);
                break;
            case Param.LIMIT_RATE:
                result = rateDMapper.getSumPassRateList(list, startTime, endTime);
                break;
            default:
                break;
        }
        return result;
    }

    public List<GeneralVO> getEventDetail(List<String> list, String startTime, String endTime, List<DictData> eventStatis) {
        Map<String, String> dictMap = eventStatis.stream().collect(Collectors.toMap(DictData::getCode, DictData::getId));
        HashMap<String, Object> condMap = new HashMap<>();
        condMap.put("startTime", DateUtil.beginOfDay(DateUtil.parse(startTime)).toString());
        condMap.put("endTime", DateUtil.endOfDay(DateUtil.parse(endTime)).toString());
        condMap.put("ids", list);
        condMap.put(DicDataEnum.VOLTAGE_DIP.getCode(), dictMap.get(DicDataEnum.VOLTAGE_DIP.getCode())); //电压暂降
        condMap.put(DicDataEnum.SHORT_INTERRUPTIONS.getCode(), dictMap.get(DicDataEnum.SHORT_INTERRUPTIONS.getCode())); //短时中断
        condMap.put(DicDataEnum.VOLTAGE_RISE.getCode(), dictMap.get(DicDataEnum.VOLTAGE_RISE.getCode())); //电压暂升
        return eventDetailFeignClient.getEventDetailCount(condMap).getData();
    }
}
