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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.DeviceInfoParam;
import com.njcn.device.pq.pojo.param.OnlineRateParam;
import com.njcn.device.pq.pojo.vo.AreaLineInfoVO;
import com.njcn.event.pojo.po.EventDetailNew;
import com.njcn.event.pojo.po.RmpEventDetailPO;
import com.njcn.event.pojo.vo.AreaSubLineVO;
import com.njcn.event.service.majornetwork.AreaInfoService;
import com.njcn.event.common.service.EventDetailService;
import com.njcn.harmonic.api.PollutionSubstationClient;
import com.njcn.harmonic.pojo.excel.pollution.UserLinePollution;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

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

/**
 * pqs-event
 * 区域地理信息
 *
 * @author cdf
 * @date 2022/6/29
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class AreaInfoServiceImpl implements AreaInfoService {

    private final GeneralDeviceInfoClient generalDeviceInfoClient;
    private final LineFeignClient lineFeignClient;
    private final EventDetailService eventDetailService;
    private final PollutionSubstationClient pollutionSubstationClient;

    @Override
    public List<AreaSubLineVO> getAreaLineInfo(DeviceInfoParam.GridDiagram deviceInfoParam) {
        List<AreaSubLineVO> resultVOList = new ArrayList<>();
        List<String> lineIds = new ArrayList<>();
        Map<String, UserLinePollution> userMap = new HashMap<>();
        if (1 == deviceInfoParam.getType()) {
            if (CollectionUtil.isNotEmpty(deviceInfoParam.getCoutList())) {
                lineIds.addAll(deviceInfoParam.getCoutList());
            }
            if (CollectionUtil.isNotEmpty(deviceInfoParam.getAlarmList())) {
                lineIds.addAll(deviceInfoParam.getAlarmList());
            }

        } else {
            List<GeneralDeviceDTO> generalDeviceDTOList = generalDeviceInfoClient.getPracticalAllDeviceInfo(deviceInfoParam).getData();
            lineIds.addAll(generalDeviceDTOList.stream().flatMap(dto -> dto.getLineIndexes().stream()).collect(Collectors.toList()));
        }

        if (CollectionUtil.isNotEmpty(lineIds)) {
            List<AreaLineInfoVO> resList = lineFeignClient.getBaseLineAreaInfo(lineIds).getData();
            if (Objects.equals(1,deviceInfoParam.getIsPollution())) {
                OnlineRateParam.Info param = new OnlineRateParam.Info();
                param.setIds(resList.stream().map(AreaLineInfoVO::getLineId).distinct().collect(Collectors.toList()));
                param.setDicData(deviceInfoParam.getDicData());
                param.setStartTime(deviceInfoParam.getSearchBeginTime());
                param.setEndTime(deviceInfoParam.getSearchEndTime());
                userMap = pollutionSubstationClient.getSumList(param).getData();
            }

            //设置冀北告警监测点类型
            if (CollectionUtil.isNotEmpty(deviceInfoParam.getCoutList())) {
                resList.stream().filter(x -> deviceInfoParam.getCoutList().contains(x.getLineId())).forEach(x -> x.setType(0));
            }
            if (CollectionUtil.isNotEmpty(deviceInfoParam.getAlarmList())) {
                resList.stream().filter(x -> deviceInfoParam.getAlarmList().contains(x.getLineId())).forEach(x -> x.setType(1));
            }

            //查询监测点未处理暂态事件
            List<RmpEventDetailPO> eventDetails = eventDetailService.list(new LambdaQueryWrapper<RmpEventDetailPO>()
                    .in(RmpEventDetailPO::getMeasurementPointId, lineIds)
                    .ge(StringUtils.isNotBlank(deviceInfoParam.getSearchBeginTime()), RmpEventDetailPO::getStartTime, DateUtil.beginOfDay(DateUtil.parse(deviceInfoParam.getSearchBeginTime())))
                    .le(StringUtils.isNotBlank(deviceInfoParam.getSearchEndTime()), RmpEventDetailPO::getStartTime, DateUtil.endOfDay(DateUtil.parse(deviceInfoParam.getSearchEndTime())))
            );
            //根据监测点分组统计数量
            Map<String, Long> count = eventDetails.stream().collect(Collectors.groupingBy(RmpEventDetailPO::getMeasurementPointId, Collectors.counting()));

            for (AreaLineInfoVO areaLineInfoVO : resList) {
                areaLineInfoVO.setNoDealCount(0);
                if (CollectionUtil.isNotEmpty(count)) {
                    if (count.containsKey(areaLineInfoVO.getLineId())) {
                        Long aLong = count.get(areaLineInfoVO.getLineId());
                        areaLineInfoVO.setNoDealCount(Math.toIntExact(aLong));
                    }
                }
                if (userMap.containsKey(areaLineInfoVO.getLineId())) {
                    UserLinePollution userLinePollution = userMap.get(areaLineInfoVO.getLineId());
                    areaLineInfoVO.setVHarmonicValue(userLinePollution.getVHarmonicValue());
                    areaLineInfoVO.setUserList(BeanUtil.copyToList(userLinePollution.getUserList(), AreaLineInfoVO.User.class));
                }
            }

            //组装成变电站
            if (CollectionUtil.isNotEmpty(resList)) {
                Map<String, List<AreaLineInfoVO>> map = resList.stream().collect(Collectors.groupingBy(AreaLineInfoVO::getSubId));
                map.forEach((key, value) -> {
                    AreaSubLineVO areaSubLineVO = new AreaSubLineVO();
                    areaSubLineVO.setChildren(value);
                    areaSubLineVO.setSubId(key);
                    areaSubLineVO.setLat(value.get(0).getLat());
                    areaSubLineVO.setLng(value.get(0).getLng());
                    areaSubLineVO.setSubName(value.get(0).getSubName());
                    resultVOList.add(areaSubLineVO);
                });
            }
        }
        return resultVOList;
    }


    @Override
    public List<EventDetailNew> getNoDealEvents(DeviceInfoParam.BusinessParam deviceInfoParam) {
        List<EventDetailNew> resList = new ArrayList<>();
        List<GeneralDeviceDTO> generalDeviceDTOList = generalDeviceInfoClient.getPracticalAllDeviceInfo(deviceInfoParam).getData();
        List<String> lineIds = generalDeviceDTOList.stream().flatMap(dto -> dto.getLineIndexes().stream()).collect(Collectors.toList());

        if (CollectionUtil.isNotEmpty(lineIds)) {
            List<AreaLineInfoVO> lineList = lineFeignClient.getBaseLineAreaInfo(lineIds).getData();
            Map<String, AreaLineInfoVO> lineMap = lineList.stream().collect(Collectors.toMap(AreaLineInfoVO::getLineId, Function.identity(), (key1, kye2) -> key1));

            //查询监测点未处理暂态事件
            List<RmpEventDetailPO> eventDetails = eventDetailService.list(new LambdaQueryWrapper<RmpEventDetailPO>()
                    .and(x -> x.in(RmpEventDetailPO::getMeasurementPointId, lineIds)
                            .isNull(RmpEventDetailPO::getEventassIndex)
                            .or()
                            .eq(RmpEventDetailPO::getEventassIndex, "")
                    )
                    .ge(StringUtils.isNotBlank(deviceInfoParam.getSearchBeginTime()), RmpEventDetailPO::getStartTime, DateUtil.beginOfDay(DateUtil.parse(deviceInfoParam.getSearchBeginTime())))
                    .le(StringUtils.isNotBlank(deviceInfoParam.getSearchEndTime()), RmpEventDetailPO::getStartTime, DateUtil.endOfDay(DateUtil.parse(deviceInfoParam.getSearchEndTime())))
                    .orderByDesc(RmpEventDetailPO::getStartTime).last("limit 100"));
            EventDetailNew eventDetailNew;
            for (RmpEventDetailPO eventDetail : eventDetails) {
                eventDetailNew = BeanUtil.copyProperties(eventDetail, EventDetailNew.class);
                //监测点id
                eventDetailNew.setLineId(eventDetail.getMeasurementPointId());
                //特征幅值 需要转成百分比*100
                eventDetailNew.setFeatureAmplitude(roundHalfUp(eventDetail.getFeatureAmplitude()*100));
                //持续时间
                eventDetailNew.setDuration(eventDetail.getDuration());

                if (lineMap.containsKey(eventDetail.getMeasurementPointId())) {
                    AreaLineInfoVO areaLineInfoVO = lineMap.get(eventDetail.getMeasurementPointId());
                    eventDetailNew.setLineName(areaLineInfoVO.getLineName());
                    eventDetailNew.setLng(areaLineInfoVO.getLng());
                    eventDetailNew.setLat(areaLineInfoVO.getLat());
                    resList.add(eventDetailNew);
                }
            }
        }
        return resList;
    }
    private Double roundHalfUp(double num) {
        if (num == 3.14159) {
            return num;
        }
        BigDecimal b = new BigDecimal(num);
        //保留2位小数
        return com.njcn.harmonic.utils.PubUtils.dataLimits(b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
    }
    @Override
    public List<EventDetailNew> getNoDealEventsByLineId(String id, String searchBeginTime, String searchEndTime) {
        List<AreaLineInfoVO> lineList = lineFeignClient.getBaseLineAreaInfo(Stream.of(id).collect(Collectors.toList())).getData();

        List<EventDetailNew> resList = new ArrayList<>();
        //查询监测点未处理暂态事件
        List<RmpEventDetailPO> eventDetails = eventDetailService.list(new LambdaQueryWrapper<RmpEventDetailPO>()
                .eq(RmpEventDetailPO::getMeasurementPointId, id)
                .ge(StringUtils.isNotBlank(searchBeginTime), RmpEventDetailPO::getStartTime, DateUtil.beginOfDay(DateUtil.parse(searchBeginTime)))
                .le(StringUtils.isNotBlank(searchEndTime), RmpEventDetailPO::getStartTime, DateUtil.endOfDay(DateUtil.parse(searchEndTime)))

        );
        EventDetailNew eventDetailNew;
        for (RmpEventDetailPO eventDetail : eventDetails) {
            eventDetailNew = BeanUtil.copyProperties(eventDetail, EventDetailNew.class);
            //监测点id
            eventDetailNew.setLineId(eventDetail.getMeasurementPointId());
            //持续时间
            eventDetailNew.setDuration(eventDetail.getDuration());
            //特征幅值
            eventDetailNew.setFeatureAmplitude(eventDetail.getFeatureAmplitude());
            if (CollectionUtil.isNotEmpty(lineList)) {
                eventDetailNew.setGdName(lineList.get(0).getGdName());
                eventDetailNew.setSubName(lineList.get(0).getSubName());
                eventDetailNew.setLineName(lineList.get(0).getLineName());
            }
            resList.add(eventDetailNew);
        }
        return resList;
    }


}
