package com.njcn.event.service.majornetwork.Impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.common.pojo.dto.SimpleDTO;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.pojo.param.StatisticsBizBaseParam;
import com.njcn.device.biz.commApi.CommTerminalGeneralClient;
import com.njcn.device.biz.pojo.dto.DeptGetChildrenMoreDTO;
import com.njcn.device.biz.pojo.dto.LineDevGetDTO;
import com.njcn.device.biz.pojo.param.DeptGetLineParam;
import com.njcn.device.pms.api.DistributionMonitorClient;
import com.njcn.device.pms.api.MonitorClient;
import com.njcn.device.pms.api.PmsGeneralDeviceInfoClient;
import com.njcn.device.pms.pojo.dto.PmsGeneralDeviceDTO;
import com.njcn.device.pms.pojo.dto.PmsMonitorDTO;
import com.njcn.device.pms.pojo.dto.PwPmsMonitorDTO;
import com.njcn.device.pms.pojo.param.PmsDeviceInfoParam;
import com.njcn.device.pms.pojo.param.PmsMonitorParam;
import com.njcn.device.pms.pojo.po.Monitor;
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.param.GridDiagramParam;
import com.njcn.device.pq.pojo.vo.AreaLineInfoVO;
import com.njcn.device.pq.pojo.vo.GridDiagramVO;
import com.njcn.device.pq.pojo.vo.LineDetailVO;
import com.njcn.event.enums.EventResponseEnum;
import com.njcn.event.mapper.majornetwork.RMpEventDetailMMapper;
import com.njcn.event.common.mapper.RmpEventDetailMapper;
import com.njcn.event.pojo.dto.EventCount;
import com.njcn.event.pojo.param.EventBaseParam;
import com.njcn.event.pojo.param.UniversalFrontEndParam;
import com.njcn.event.pojo.po.RMpEventDetailM;
import com.njcn.event.pojo.po.RmpEventDetailPO;
import com.njcn.event.pojo.vo.AdvanceEventDetailVO;
import com.njcn.event.pojo.vo.EventDetailVO;
import com.njcn.event.pojo.vo.RmpEventDetailVO;
import com.njcn.event.service.majornetwork.RmpEventDetailService;
import com.njcn.harmonic.pojo.param.StatSubstationBizBaseParam;
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.user.api.DeptFeignClient;
import com.njcn.user.pojo.dto.DeptDTO;
import com.njcn.web.factory.PageFactory;
import com.njcn.web.pojo.param.BaseParam;
import com.njcn.web.utils.RequestUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;


/**
 * 暂态事件明细
 *
 * @author yzh
 * @date 2022/10/12
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class RmpEventDetailServiceImpl extends ServiceImpl<RmpEventDetailMapper, RmpEventDetailPO> implements RmpEventDetailService {

    private final RmpEventDetailMapper rmpEventDetailMapper;

    private final DeptFeignClient deptFeignClient;

    private final DicDataFeignClient dicDataFeignClient;

    private final PmsGeneralDeviceInfoClient pmsGeneralDeviceInfoClient;

    private final MonitorClient monitorClient;

    private final LineFeignClient lineFeignClient;

    private final DistributionMonitorClient distributionMonitorClient;

    private final GeneralDeviceInfoClient generalDeviceInfoClient;

    private final CommTerminalGeneralClient commTerminalGeneralClient;

    private final RMpEventDetailMMapper eventDetailMMapper;


    /**
     * 获取暂态事件明细
     *
     * @param param 条件参数
     * @return 暂态事件明细
     */
    @Override
    public Page<RmpEventDetailVO> getRmpEventDetail(UniversalFrontEndParam param) {
        // 获取当前用户的部门的子部门信息
        PmsDeviceInfoParam pmsDeviceInfoParam = new PmsDeviceInfoParam();
        pmsDeviceInfoParam.setDeptIndex(param.getId());
        pmsDeviceInfoParam.setStatisticalType(new SimpleDTO());
        List<PmsGeneralDeviceDTO> data = pmsGeneralDeviceInfoClient.getPmsDeviceInfoWithInOrg(pmsDeviceInfoParam).getData();

        if (CollectionUtil.isEmpty(data)) {
            return new Page<>();
        }

        // 查询事件类型字典表
        List<DictData> eventStatisData = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.EVENT_STATIS.getCode()).getData();

        // 查询监测点类别
        String monitorSort = dicDataFeignClient.getDicDataById(param.getMonitorSort().get(0)).getData().getName();

        // 取出所有监测点
        List<String> monitorIds = data.stream().flatMap(pmsGeneralDeviceDTO -> pmsGeneralDeviceDTO.getMonitorIdList().stream()).collect(Collectors.toList());
        if (CollUtil.isEmpty(monitorIds)) {
            return new Page<>();
        }
        // 查询监测点信息
        PmsMonitorParam pmsMonitorParam = new PmsMonitorParam();
        if (!StringUtils.isEmpty(param.getMonitorName())) {
            pmsMonitorParam.setMonitorName(param.getMonitorName());
        }
        pmsMonitorParam.setMonitorIds(monitorIds);
        List<PmsMonitorDTO> monitorInfo = monitorClient.getMonitorInfoListByCond(pmsMonitorParam).getData();
        if (CollectionUtil.isEmpty(monitorInfo)) {
            return new Page<>();
        }
        // 取出所有监测点
        List<String> monitorList = monitorInfo.stream().map(PmsMonitorDTO::getId).collect(Collectors.toList());
        // 获取暂态事件明细
        Page<RmpEventDetailPO> rmpEventDetailPOPage = rmpEventDetailMapper.selectPage(new Page<>(param.getPageNum(), param.getPageSize()), new LambdaQueryWrapper<RmpEventDetailPO>()
                .in(CollUtil.isNotEmpty(monitorList), RmpEventDetailPO::getMeasurementPointId, monitorList)
                .ge(StrUtil.isNotBlank(param.getStartTime()), RmpEventDetailPO::getStartTime, DateUtil.beginOfDay(DateUtil.parse(param.getStartTime())))
                .le(StrUtil.isNotBlank(param.getEndTime()), RmpEventDetailPO::getStartTime, DateUtil.endOfDay(DateUtil.parse(param.getEndTime())))
                .orderByDesc(RmpEventDetailPO::getStartTime)
        );


        if (CollectionUtil.isEmpty(rmpEventDetailPOPage.getRecords())) {
            return new Page<>();
        }

        // 蒋监测点信息转换成map集合
        //Map<String, String> monitorInfoMap = monitorInfo.stream().collect(Collectors.toMap(PmsMonitorDTO::getId, PmsMonitorDTO::getName));
        // 将事件类型转换成map集合
        Map<String, String> eventStatisDataMap = eventStatisData.stream().collect(Collectors.toMap(DictData::getId, DictData::getName));

        // 属性赋值
        List<RmpEventDetailVO> collect = rmpEventDetailPOPage.getRecords().stream().map(po -> {
            RmpEventDetailVO vo = new RmpEventDetailVO();
            BeanUtils.copyProperties(po, vo);
            for (PmsMonitorDTO dto : monitorInfo) {
                if (dto.getId().equals(po.getMeasurementPointId())) {
                    vo.setDeptName(dto.getOrgName());
                    vo.setMonitorSort(monitorSort);
                    vo.setMeasurementPointName(dto.getName());
                    vo.setEventType(eventStatisDataMap.get(po.getEventType()));
                    vo.setPowerStationName(dto.getPowerrName());
                }
            }
            return vo;
        }).collect(Collectors.toList());
        Page<RmpEventDetailVO> page = BeanUtil.copyProperties(rmpEventDetailPOPage, Page.class);
        page.setRecords(collect);
        return page;

    }

    /**
     * 获取暂态指标类型列表
     *
     * @return 暂态指标类型列表
     */
    @Override
    public List<DictData> getEventStatisList() {
        return dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.EVENT_STATIS.getCode()).getData();
    }


    @Override
    public RmpEventDetailVO getTransientDetailById(String eventId, String sysType, Integer smallType) {
        RmpEventDetailVO rmpEventDetailVO = new RmpEventDetailVO();
        RmpEventDetailPO rmpEventDetailPO = this.getById(eventId);
        if (Objects.isNull(rmpEventDetailPO)) {
            throw new BusinessException(EventResponseEnum.EVENT_NOT_FOUND);
        }
        List<String> monitorIds = Stream.of(rmpEventDetailPO.getLineId()).collect(Collectors.toList());
        BeanUtils.copyProperties(rmpEventDetailPO, rmpEventDetailVO);
        if ("pms".equals(sysType)) {

            if (Objects.isNull(smallType) || smallType == 0) {
                List<Monitor> monitorList = monitorClient.getMonitorList(monitorIds).getData();
                if (CollectionUtil.isNotEmpty(monitorList)) {
                    rmpEventDetailVO.setMeasurementPointName(monitorList.get(0).getName());
                    rmpEventDetailVO.setPowerStationName(monitorList.get(0).getPowerrName());
                }

            } else {
                //配网
                List<PwPmsMonitorDTO> pwPmsMonitorDTOList = distributionMonitorClient.pwMonitorAreaDetailInfo(monitorIds).getData();
                if (CollectionUtil.isNotEmpty(pwPmsMonitorDTOList)) {
                    rmpEventDetailVO.setMeasurementPointName(pwPmsMonitorDTOList.get(0).getMonitorName());
                    rmpEventDetailVO.setPowerStationName(pwPmsMonitorDTOList.get(0).getPowerName());
                }
            }

        } else {
            List<AreaLineInfoVO> lineRes = lineFeignClient.getBaseLineAreaInfo(monitorIds).getData();
            if (CollectionUtil.isNotEmpty(lineRes)) {
                rmpEventDetailVO.setMeasurementPointName(lineRes.get(0).getLineName());
                rmpEventDetailVO.setPowerStationName(lineRes.get(0).getSubName());
            }
        }
        return rmpEventDetailVO;
    }

    @Override
    public Page<AdvanceEventDetailVO> querySagEvents(BaseParam baseParam) {
        Page<AdvanceEventDetailVO> pageResult = new Page<>(PageFactory.getPageNum(baseParam), PageFactory.getPageSize(baseParam));
        List<String> lineIds = generalDeviceInfoClient.deptGetRunLineEvent(RequestUtil.getDeptIndex()).getData();
        if (CollUtil.isNotEmpty(lineIds)) {
            LambdaQueryWrapper<RmpEventDetailPO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.isNull(RmpEventDetailPO::getEventassIndex);
            Page<RmpEventDetailPO> poPage = this.page(new Page<>(PageFactory.getPageNum(baseParam), PageFactory.getPageSize(baseParam)), lambdaQueryWrapper);

            List<String> tempLineIds = poPage.getRecords().stream().map(RmpEventDetailPO::getLineId).distinct().collect(Collectors.toList());

            List<AreaLineInfoVO> temLine = lineFeignClient.getBaseLineAreaInfo(tempLineIds).getData();
            Map<String, AreaLineInfoVO> map = temLine.stream().collect(Collectors.toMap(AreaLineInfoVO::getLineId, Function.identity()));

            List<AdvanceEventDetailVO> advanceEventDetailVOList = BeanUtil.copyToList(poPage.getRecords(), AdvanceEventDetailVO.class);
            advanceEventDetailVOList = advanceEventDetailVOList.stream().peek(item -> {
                if (map.containsKey(item.getLineId())) {
                    item.setGdName(map.get(item.getLineId()).getGdName());
                    item.setSubName(map.get(item.getLineId()).getSubName());
                    switch (item.getDealFlag()) {
                        case 0:
                            item.setFeatureAmplitudeFlag(EnumFlag.UNTREATED.getDescription());
                            break;
                        case 1:
                            item.setFeatureAmplitudeFlag(EnumFlag.PROCESSED.getDescription());
                            break;
                        case 2:
                            item.setFeatureAmplitudeFlag(EnumFlag.NODATA.getDescription());
                            break;
                        case 3:
                            item.setFeatureAmplitudeFlag(EnumFlag.PROCESSFAIL.getDescription());
                            break;
                        default:
                            throw new IllegalStateException("未发现的类型: " + item.getDealFlag());
                    }
                    //录波文件
                    if (Objects.nonNull(item.getFileFlag()) && item.getFileFlag() == 1) {
                        item.setBoFileFlag(EnumFlag.EXIST.description);
                    } else {
                        item.setBoFileFlag(EnumFlag.ABSENCE.description);
                    }

                }
            }).collect(Collectors.toList());

            pageResult.setRecords(advanceEventDetailVOList);
            pageResult.setTotal(poPage.getTotal());
            pageResult.setPages(poPage.getPages());
            pageResult.setSize(poPage.getSize());
            pageResult.setCurrent(poPage.getCurrent());
            return pageResult;
        }
        return pageResult;
    }


    @Override
    public RmpEventDetailPO queryEventDetailByEventId(String eventId) {
        return this.getById(eventId);
    }

    @Override
    public GridDiagramVO getEventLevelEvaluation(StatSubstationBizBaseParam param) {
        GridDiagramVO gridDiagramVO = new GridDiagramVO();
        List<GridDiagramVO.LineStatistics> info = new ArrayList<>();
        List<GridDiagramVO.LineStatistics> gwInfo = new ArrayList<>();

        //获取部门数据关系
        List<DeptDTO> data = deptFeignClient.getDepSonDetailByDeptId(param.getId()).getData();
        List<String> deptIDS = data.stream().map(x -> x.getId()).collect(Collectors.toList());
        DeptGetLineParam deptGetLineParam = new DeptGetLineParam();
        deptGetLineParam.setDeptId(param.getId());
        deptGetLineParam.setLineRunFlag(0);
        List<DeptGetChildrenMoreDTO> deptGetChildrenMoreDTOS = commTerminalGeneralClient.deptGetLine(deptGetLineParam).getData();
        List<LineDevGetDTO> collect = deptGetChildrenMoreDTOS.stream()
                .filter(x -> deptIDS.contains(x.getUnitId()))
                .flatMap(x -> x.getLineBaseList().stream()).collect(Collectors.toList());

        List<String> lineAllIds = collect.stream().map(LineDevGetDTO::getPointId).collect(Collectors.toList());
        List<String> gwLineAllIds = collect.stream().filter(x -> 1 == x.getIsUpToGrid()).map(LineDevGetDTO::getPointId).collect(Collectors.toList());
        List<RmpEventDetailPO> list1 = this.list(new LambdaQueryWrapper<RmpEventDetailPO>()
                .in(CollUtil.isNotEmpty(lineAllIds), RmpEventDetailPO::getMeasurementPointId, lineAllIds)
                .ge(StrUtil.isNotBlank(param.getStartTime()), RmpEventDetailPO::getStartTime, DateUtil.beginOfDay(DateUtil.parse(param.getStartTime())))
                .le(StrUtil.isNotBlank(param.getEndTime()), RmpEventDetailPO::getStartTime, DateUtil.endOfDay(DateUtil.parse(param.getEndTime())))
        );
        List<RmpEventDetailPO> list = list1.stream().filter(x -> param.getIds().contains(x.getEventType())).collect(Collectors.toList());

        Map<String, DeptGetChildrenMoreDTO> deptLineMap = deptGetChildrenMoreDTOS.stream().collect(Collectors.toMap(DeptGetChildrenMoreDTO::getUnitId, Function.identity()));
        GridDiagramVO.LineStatistics lineStatistics;
        GridDiagramVO.LineStatistics gwLineStatistics;
        for (DeptDTO datum : data) {
            if (deptLineMap.containsKey(datum.getId())) {
                lineStatistics = new GridDiagramVO.LineStatistics();
                lineStatistics.setOrgId(datum.getId());
                lineStatistics.setOrgName(datum.getName());
                gwLineStatistics = new GridDiagramVO.LineStatistics();
                gwLineStatistics.setOrgId(datum.getId());
                gwLineStatistics.setOrgName(datum.getName());
                List<LineDevGetDTO> lineBaseList = deptLineMap.get(datum.getId()).getLineBaseList();
                List<String> lineIds = lineBaseList.stream().map(LineDevGetDTO::getPointId).distinct().collect(Collectors.toList());
                List<String> gwLineIds = lineBaseList.stream().filter(x -> 1 == x.getIsUpToGrid()).map(LineDevGetDTO::getPointId).distinct().collect(Collectors.toList());
                long count = list.stream().filter(x -> lineIds.contains(x.getMeasurementPointId())).map(RmpEventDetailPO::getEventId).count();
                long gwCount = list.stream().filter(x -> gwLineIds.contains(x.getMeasurementPointId())).map(RmpEventDetailPO::getEventId).count();
                lineStatistics.setCount(count);
                gwLineStatistics.setCount(gwCount);
                info.add(lineStatistics);
                gwInfo.add(gwLineStatistics);
            }
        }
        gridDiagramVO.setData(setData(lineAllIds, list1));
        gridDiagramVO.setGwData(setData(gwLineAllIds, list1));
        gridDiagramVO.setInfo(info);
        gridDiagramVO.setGwInfo(gwInfo);
        return gridDiagramVO;
    }

    @Override
    public List<EventDetailVO> getEventDetailByList(GridDiagramParam param) {
        List<EventDetailVO> info = new ArrayList<>();
        //获取统计类型
        DictData dip = dicDataFeignClient.getDicDataByCode(DicDataEnum.VOLTAGE_DIP.getCode()).getData();
        DictData rise = dicDataFeignClient.getDicDataByCode(DicDataEnum.VOLTAGE_RISE.getCode()).getData();
        DictData interruptions = dicDataFeignClient.getDicDataByCode(DicDataEnum.SHORT_INTERRUPTIONS.getCode()).getData();

        List<GeneralDeviceDTO> data = generalDeviceInfoClient.getPracticalRunDeviceInfo(param.getDeviceInfoParam()).getData();
        List<String> lineIds = data.stream().flatMap(x -> x.getLineIndexes().stream()).distinct().collect(Collectors.toList());
        List<RmpEventDetailPO> list = this.list(new LambdaQueryWrapper<RmpEventDetailPO>()
                .select(RmpEventDetailPO::getEventId, RmpEventDetailPO::getMeasurementPointId, RmpEventDetailPO::getEventType, RmpEventDetailPO::getSeverity)
                .in(CollUtil.isNotEmpty(lineIds), RmpEventDetailPO::getMeasurementPointId, lineIds)
                .ge(StrUtil.isNotBlank(param.getSearchBeginTime()), RmpEventDetailPO::getStartTime, DateUtil.beginOfDay(DateUtil.parse(param.getSearchBeginTime())))
                .le(StrUtil.isNotBlank(param.getSearchEndTime()), RmpEventDetailPO::getStartTime, DateUtil.endOfDay(DateUtil.parse(param.getSearchEndTime())))
        );
        Map<String, LineDetailVO.Detail> lineMap = new HashMap<>();
        if (CollUtil.isNotEmpty(lineIds)) {
            List<LineDetailVO.Detail> lines = lineFeignClient.getLineDetailByIds(lineIds).getData();
            lineMap = lines.stream().collect(Collectors.toMap(LineDetailVO.Detail::getLineId, Function.identity()));
        }
        EventDetailVO vo;
        for (GeneralDeviceDTO datum : data) {
            vo = new EventDetailVO();
            vo.setId(datum.getIndex());
            vo.setName(datum.getName());
            List<RmpEventDetailPO> detailPOList = list.stream().filter(x -> datum.getLineIndexes().contains(x.getMeasurementPointId())).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(detailPOList)) {
                vo.setSwellTimes(detailPOList.stream().filter(x -> x.getEventType().equals(rise.getId())).count());
                vo.setSwellTimesIds(eventLine(detailPOList, rise.getId(), lineMap));

                vo.setSagTimes(detailPOList.stream().filter(x -> x.getEventType().equals(dip.getId())).count());
                vo.setSagTimesIds(eventLine(detailPOList, dip.getId(), lineMap));

                vo.setInterruptTimes(detailPOList.stream().filter(x -> x.getEventType().equals(interruptions.getId())).count());
                vo.setInterruptTimesIds(eventLine(detailPOList, interruptions.getId(), lineMap));

                double v90 = detailPOList.stream().filter(x -> x.getSeverity() * 100 <= 90).count() * 100.0 / detailPOList.size();
                double v50 = detailPOList.stream().filter(x -> x.getSeverity() * 100 <= 50).count() * 100.0 / detailPOList.size();
                double v20 = detailPOList.stream().filter(x -> x.getSeverity() * 100 <= 20).count() * 100.0 / detailPOList.size();
                vo.setRate90(NumberUtil.round(v90, 2).doubleValue());
                vo.setRate50(NumberUtil.round(v50, 2).doubleValue());
                vo.setRate20(NumberUtil.round(v20, 2).doubleValue());
            } else {
                vo.setSwellTimes(0L);
                vo.setSagTimes(0L);
                vo.setInterruptTimes(0L);
                vo.setRate90(0.0D);
                vo.setRate50(0.0D);
                vo.setRate20(0.0D);
            }
            info.add(vo);
        }
        return info;
    }

    public List<EventCount.Detail> eventLine(List<RmpEventDetailPO> detailPOList, String dicData, Map<String, LineDetailVO.Detail> lineMap) {
        List<EventCount.Detail> info = new ArrayList<>();
        Map<String, Long> collect = detailPOList.stream().filter(x -> x.getEventType().equals(dicData))
                .collect(Collectors.groupingBy(RmpEventDetailPO::getMeasurementPointId, Collectors.counting()));
        collect.forEach((key, value) -> {
            if (lineMap.containsKey(key)) {
                LineDetailVO.Detail detail1 = lineMap.get(key);
                EventCount.Detail detail = new EventCount.Detail();
                detail.setLineId(key);
                detail.setDicData(dicData);
                detail.setLineName(detail1.getLineName());
                detail.setDevName(detail1.getDevName());
                detail.setSubName(detail1.getSubName());
                detail.setIp(detail1.getIp());
                detail.setCount(BigDecimal.valueOf(value));
                info.add(detail);
            }
        });
        info.sort(Comparator.comparing(EventCount.Detail::getCount).reversed());
        return info;
    }

    @Override
    public RMpEventDetailM getEventDetailByLine(StatisticsBizBaseParam param) {
        RMpEventDetailM rMpEventDetailM = eventDetailMMapper.selectOne(new LambdaQueryWrapper<RMpEventDetailM>()
                .eq(RMpEventDetailM::getMeasurementPointId, param.getId())
                .ge(StrUtil.isNotBlank(param.getStartTime()), RMpEventDetailM::getDataDate, DateUtil.beginOfDay(DateUtil.parse(param.getStartTime())))
                .le(StrUtil.isNotBlank(param.getEndTime()), RMpEventDetailM::getDataDate, DateUtil.endOfDay(DateUtil.parse(param.getEndTime())))
        );
        return rMpEventDetailM;
    }

    @Override
    public List<Map<String, Object>> getImMonitorEvents(EventBaseParam param) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        DictData eventDic = dicDataFeignClient.getDicDataByCodeAndType(DicDataEnum.VOLTAGE_DIP.getCode(), DicDataTypeEnum.EVENT_STATIS.getCode()).getData();
        DictData dictData = dicDataFeignClient.getDicDataByCodeAndType(DicDataEnum.MOST_IMPORMENT.getCode(), DicDataTypeEnum.DEV_GRADE.getCode()).getData();

        QueryWrapper<RmpEventDetailPO> queryWrapper = new QueryWrapper<>();

        if (StrUtil.isNotBlank(param.getLineId())) {
            queryWrapper.eq("measurement_point_id", param.getSearchValue());
        } else {
            List<String> lineIds = lineFeignClient.getLevelMonitorIdByDept(dictData.getId(), param.getDeptId()).getData();
            if (CollUtil.isEmpty(lineIds)) {
                return mapList;
            }
            queryWrapper.in("measurement_point_id", lineIds);
        }

        //lineFeignClient.getLevelMonitorIdByDept(dictData.getId(),)
        queryWrapper.select("measurement_point_id as lineId", "count(event_id) as eventCount").between("start_time", param.getSearchBeginTime(), param.getSearchEndTime())
                .eq("event_type", eventDic.getId())
                .groupBy("measurement_point_id");
        mapList = this.baseMapper.selectMaps(queryWrapper);
        if (CollUtil.isEmpty(mapList)) {
            return mapList;
        }
        List<String> ids = mapList.stream().map(it -> it.get("lineId").toString()).distinct().collect(Collectors.toList());
        List<AreaLineInfoVO> lineList = lineFeignClient.getBaseLineAreaInfo(ids).getData();
        Map<String, AreaLineInfoVO> lineMap = lineList.stream().collect(Collectors.toMap(AreaLineInfoVO::getLineId, Function.identity()));

        mapList.forEach(item -> {
            AreaLineInfoVO tem = lineMap.get(item.get("lineId").toString());
            item.put("lineName", tem.getVoltageName() + "_" + tem.getLineName());
        });

        return mapList;
    }

    @Override
    public List<EventCount> getEventCount(GridDiagramParam param) {
        List<EventCount> eventCounts = rmpEventDetailMapper.getEventCount(param.getSearchBeginTime(), param.getSearchEndTime());
        Map<String, EventCount> eventMap = eventCounts.stream().collect(Collectors.toMap(EventCount::getLineId, pojo -> pojo));
        List<EventCount> eventCountList = new ArrayList<>();
        for (String id : param.getIds()) {
            EventCount eventCountTemp = eventMap.get(id);
            if (Objects.isNull(eventCountTemp)) {
                eventCountTemp = new EventCount(id);
            }
            eventCountList.add(eventCountTemp);
        }
        return eventCountList;
    }

    @Override
    public Page<AdvanceEventDetailVO> getEventByLineIdsCount(EventBaseParam.Info param) {
        Page<AdvanceEventDetailVO> pageResult = new Page<>();
        param.setLineOrDevice(0);
        param.setDeptIndex(param.getDeptIndex());
        param.setStatisticalType(new SimpleDTO());
        //获取终端台账类信息
        List<GeneralDeviceDTO> deviceInfo = generalDeviceInfoClient.getPracticalRunDeviceInfo(param).getData();
        List<String> ids = deviceInfo.stream().flatMap(x -> x.getLineIndexes().stream()).distinct().collect(Collectors.toList());
        Page<RmpEventDetailPO> poPage = this.page(new Page<>(param.getPageNum(), param.getPageSize()), new LambdaQueryWrapper<RmpEventDetailPO>()
                .in(CollUtil.isNotEmpty(ids), RmpEventDetailPO::getLineId, ids)
                .eq(StrUtil.isNotBlank(param.getDicData()), RmpEventDetailPO::getEventType, param.getDicData())
                .ge(StrUtil.isNotBlank(param.getSearchBeginTime()), RmpEventDetailPO::getStartTime, DateUtil.beginOfDay(DateUtil.parse(param.getSearchBeginTime())))
                .le(StrUtil.isNotBlank(param.getSearchEndTime()), RmpEventDetailPO::getStartTime, DateUtil.endOfDay(DateUtil.parse(param.getSearchEndTime())))
                .orderByDesc(RmpEventDetailPO::getStartTime)
        );
        List<String> tempLineIds = poPage.getRecords().stream().map(RmpEventDetailPO::getLineId).distinct().collect(Collectors.toList());
        if(CollUtil.isNotEmpty(tempLineIds)){
            List<AreaLineInfoVO> temLine = lineFeignClient.getBaseLineAreaInfo(tempLineIds).getData();
            Map<String, AreaLineInfoVO> map = temLine.stream().collect(Collectors.toMap(AreaLineInfoVO::getLineId, Function.identity()));
            List<AdvanceEventDetailVO> advanceEventDetailVOList = BeanUtil.copyToList(poPage.getRecords(), AdvanceEventDetailVO.class);
            advanceEventDetailVOList = advanceEventDetailVOList.stream().peek(item -> {
                if (map.containsKey(item.getLineId())) {
                    item.setGdName(map.get(item.getLineId()).getGdName());
                    item.setSubName(map.get(item.getLineId()).getSubName());
                    item.setLineName(map.get(item.getLineId()).getLineName());
                    item.setLoadType(map.get(item.getLineId()).getLoadType());
                    item.setObjName(map.get(item.getLineId()).getObjName());
                    switch (item.getDealFlag()) {
                        case 0:
                            item.setFeatureAmplitudeFlag(EnumFlag.UNTREATED.getDescription());
                            break;
                        case 1:
                            item.setFeatureAmplitudeFlag(EnumFlag.PROCESSED.getDescription());
                            break;
                        case 2:
                            item.setFeatureAmplitudeFlag(EnumFlag.NODATA.getDescription());
                            break;
                        case 3:
                            item.setFeatureAmplitudeFlag(EnumFlag.PROCESSFAIL.getDescription());
                            break;
                        default:
                            throw new IllegalStateException("未发现的类型: " + item.getDealFlag());
                    }
                    //录波文件
                    if (Objects.nonNull(item.getFileFlag()) && item.getFileFlag() == 1) {
                        item.setBoFileFlag(EnumFlag.EXIST.description);
                    } else {
                        item.setBoFileFlag(EnumFlag.ABSENCE.description);
                    }

                }
            }).collect(Collectors.toList());
            pageResult.setRecords(advanceEventDetailVOList);
        }
        pageResult.setTotal(poPage.getTotal());
        pageResult.setPages(poPage.getPages());
        pageResult.setSize(poPage.getSize());
        pageResult.setCurrent(poPage.getCurrent());
        return pageResult;

    }


    private List<Double> setData(List<String> gwLineAllIds, List<RmpEventDetailPO> list) {
        List<Double> info = new ArrayList<>();
        long count90 = list.stream()
                .filter(x -> ObjectUtil.isNotNull(x.getSeverity()))
                .filter(x -> gwLineAllIds.contains(x.getMeasurementPointId()))
                .filter(x -> 0.9 > x.getSeverity()).count();
        long count50 = list.stream()
                .filter(x -> ObjectUtil.isNotNull(x.getSeverity()))
                .filter(x -> gwLineAllIds.contains(x.getMeasurementPointId()))
                .filter(x -> 0.5 > x.getSeverity()).count();
        if (count90 > 0) {
            info.add(NumberUtil.round(count90 * 100.0 / list.size(), 2).doubleValue());
        } else {
            info.add(0.0);
        }
        if (count50 > 0) {
            info.add(NumberUtil.round(count50 * 100.0 / list.size(), 2).doubleValue());
        } else {
            info.add(0.0);
        }
        return info;
    }

    /**
     * 内部枚举类：高级算法处理事件的标识描述
     */
    enum EnumFlag {
        PROCESSED(1, "计算成功"), UNTREATED(0, "未计算"), EXIST(1, "存在"), ABSENCE(0, "不存在"), NODATA(2, "无结果"), PROCESSFAIL(3, "计算失败");

        private final Integer code;
        private final String description;

        EnumFlag(Integer code, String description) {
            this.code = code;
            this.description = description;
        }

        public Integer getCode() {
            return code;
        }

        public String getDescription() {
            return description;
        }
    }

}


