package com.njcn.harmonic.service.specialanalysis.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.njcn.common.pojo.param.StatisticsBizBaseParam;
import com.njcn.device.pms.api.PwMonitorClient;
import com.njcn.device.pms.pojo.dto.PwPmsMonitorDTO;
import com.njcn.device.pms.pojo.param.PwPmsMonitorParam;
import com.njcn.harmonic.pojo.po.RStatOrgPvAreaPO;
import com.njcn.harmonic.pojo.po.RStatOrgPvMonitorTypePO;
import com.njcn.harmonic.pojo.po.RStatOrgPvVoltagePO;
import com.njcn.harmonic.pojo.vo.RStatOrgPvVO;
import com.njcn.harmonic.service.specialanalysis.DistributedPvOverviewService;
import com.njcn.harmonic.service.specialanalysis.RStatOrgPvAreaService;
import com.njcn.harmonic.service.specialanalysis.RStatOrgPvMonitorTypeService;
import com.njcn.harmonic.service.specialanalysis.RStatOrgPvVoltageService;
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 lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author yzh
 * @date 2022/11/24
 */

@Slf4j
@Service
@RequiredArgsConstructor
public class DistributedPvOverviewServiceImpl implements DistributedPvOverviewService {

    private final PwMonitorClient monitorClient;

    private final RStatOrgPvAreaService rStatOrgPvAreaService;
    private final RStatOrgPvVoltageService rStatOrgPvVoltageService;
    private final RStatOrgPvMonitorTypeService rStatOrgPvMonitorTypeService;

    private final DicDataFeignClient dicDataFeignClient;

    /**
     * 按区域获取分布式光伏总览
     *
     * @param param 条件参数
     * @return com.njcn.common.pojo.response.HttpResult<java.util.List < com.njcn.harmonic.pojo.vo.RMpPvPowerDetailVO>>
     * @author yzh
     * @date 2022/11/24
     */

    @Override
    public RStatOrgPvVO getDistributedPvOverviewArea(StatisticsBizBaseParam param) {
        // 获取监测点信息
        List<PwPmsMonitorDTO> monitorDtoList = getMonitorDtoList(param);
        if (CollUtil.isEmpty(monitorDtoList)) {
            return new RStatOrgPvVO();
        }
        // 取出单位
        List<String> deptIds = monitorDtoList.stream().map(PwPmsMonitorDTO::getOrgId).collect(Collectors.toList());
        Map<String, String> deptMap =
                monitorDtoList.stream()
                        .collect(Collectors.toMap(PwPmsMonitorDTO::getOrgId, PwPmsMonitorDTO::getOrgName,(key1,key2)->key2));

        // 按电压等级获取分布式光伏总览
        LambdaQueryWrapper<RStatOrgPvAreaPO> lqw = new LambdaQueryWrapper<>();
        lqw.in(RStatOrgPvAreaPO::getOrgNo, deptIds);
        lqw.ge(StrUtil.isNotBlank(param.getStartTime()), RStatOrgPvAreaPO::getDataDate, param.getStartTime());
        lqw.le(StrUtil.isNotBlank(param.getEndTime()), RStatOrgPvAreaPO::getDataDate, param.getEndTime());
        List<RStatOrgPvAreaPO> poList = rStatOrgPvAreaService.list(lqw);
        if (CollUtil.isEmpty(poList)) {
            new RStatOrgPvVO();
        }
        // 查询台区电能质量事件类型
        List<DictData> areaPqEventType = dicDataFeignClient
                .getDicDataByTypeCode(DicDataTypeEnum.AREA_PQ_EVENT_TYPE.getCode()).getData();
        // 将事件类型转换成map集合l..
        Map<String, String> areaPqEventTypeMap = areaPqEventType.
                stream().collect(Collectors.toMap(DictData::getId, DictData::getCode));
        // 将查询出来的数据转换成map集合
        Map<String, List<RStatOrgPvAreaPO>> poMap = poList.stream().collect(Collectors.groupingBy(RStatOrgPvAreaPO::getOrgNo));
        RStatOrgPvVO result = new RStatOrgPvVO();
        List<RStatOrgPvVO.FlowReversal> flowReversalList = new ArrayList<>();
        List<RStatOrgPvVO.VoltageOutOfLimit> voltageOutOfLimitList = new ArrayList<>();
        List<RStatOrgPvVO.PvPermeability> pvPermeabilityList = new ArrayList<>();
        List<RStatOrgPvVO.LowPowerFactor> lowPowerFactorList = new ArrayList<>();
        poMap.forEach((key, value) -> {
            if(deptMap.containsKey(key)){
                key=deptMap.get(key);
                for (RStatOrgPvAreaPO po : value) {
                    // 潮流倒送
                    if (areaPqEventTypeMap.get(po.getAreaPqEventType()).equals(DicDataEnum.EVENT_TYPE_U.getCode())){
                        RStatOrgPvVO.FlowReversal flowReversal = new RStatOrgPvVO.FlowReversal();
                        Integer monitorPointNum = po.getMonitorPointNum();
                        flowReversal.setMonitor(monitorPointNum.toString());
                        flowReversal.setType(key);
                        flowReversalList.add(flowReversal);
                    }
                    // 电压越限
                    if (areaPqEventTypeMap.get(po.getAreaPqEventType()).equals(DicDataEnum.EVENT_TYPE_W.getCode())){
                        RStatOrgPvVO.VoltageOutOfLimit voltageOutOfLimit = new RStatOrgPvVO.VoltageOutOfLimit();
                        Integer monitorPointNum = po.getMonitorPointNum();
                        voltageOutOfLimit.setMonitor(monitorPointNum.toString());
                        voltageOutOfLimit.setType(key);
                        voltageOutOfLimitList.add(voltageOutOfLimit);
                    }
                    // 渗透率超上限
                    if (areaPqEventTypeMap.get(po.getAreaPqEventType()).equals(DicDataEnum.PENET_LIMIT.getCode())){
                        RStatOrgPvVO.PvPermeability pvPermeability = new RStatOrgPvVO.PvPermeability();
                        Integer monitorPointNum = po.getMonitorPointNum();
                        pvPermeability.setMonitor(monitorPointNum.toString());
                        pvPermeability.setType(key);
                        pvPermeabilityList.add(pvPermeability);
                    }
                    // 低功率因数
                    if (areaPqEventTypeMap.get(po.getAreaPqEventType()).equals(DicDataEnum.EVENT_TYPE_I.getCode())){
                        RStatOrgPvVO.LowPowerFactor lowPowerFactor = new RStatOrgPvVO.LowPowerFactor();
                        Integer monitorPointNum = po.getMonitorPointNum();
                        lowPowerFactor.setMonitor(monitorPointNum.toString());
                        lowPowerFactor.setType(key);
                        lowPowerFactorList.add(lowPowerFactor);
                    }
                }
            }
        });
        result.setFlowReversal(flowReversalList);
        result.setVoltageOutOfLimit(voltageOutOfLimitList);
        result.setLowPowerFactor(lowPowerFactorList);
        result.setPvPermeability(pvPermeabilityList);
        return result;

    }

    /**
     * 按电压等级获取分布式光伏总览
     *
     * @param param 条件参数
     * @return com.njcn.common.pojo.response.HttpResult<java.util.List < com.njcn.harmonic.pojo.vo.RMpPvPowerDetailVO>>
     * @author yzh
     * @date 2022/11/24
     */
    @Override
    public RStatOrgPvVO getDistributedPvOverviewVoltage(StatisticsBizBaseParam param) {
        // 获取监测点信息
        List<PwPmsMonitorDTO> monitorDtoList = getMonitorDtoList(param);
        if (CollUtil.isEmpty(monitorDtoList)) {
            return new RStatOrgPvVO();
        }
        // 取出单位
        List<String> deptIds = monitorDtoList.stream().map(PwPmsMonitorDTO::getOrgId).collect(Collectors.toList());
        // 按电压等级获取分布式光伏总览
        LambdaQueryWrapper<RStatOrgPvVoltagePO> lqw = new LambdaQueryWrapper<>();
        lqw.in(RStatOrgPvVoltagePO::getOrgNo, deptIds);
        lqw.ge(StrUtil.isNotBlank(param.getStartTime()), RStatOrgPvVoltagePO::getDataDate, param.getStartTime());
        lqw.le(StrUtil.isNotBlank(param.getEndTime()), RStatOrgPvVoltagePO::getDataDate, param.getEndTime());
        List<RStatOrgPvVoltagePO> poList = rStatOrgPvVoltageService.list(lqw);
        if (CollUtil.isEmpty(poList)) {
            new RStatOrgPvVO();
        }
        // 查询台区电能质量事件类型
        List<DictData> areaPqEventType = dicDataFeignClient
                .getDicDataByTypeCode(DicDataTypeEnum.AREA_PQ_EVENT_TYPE.getCode()).getData();
        // 将事件类型转换成map集合l..
        Map<String, String> areaPqEventTypeMap = areaPqEventType.
                stream().collect(Collectors.toMap(DictData::getId, DictData::getCode));
        // 将查询出来的数据转换成map集合
        Map<String, List<RStatOrgPvVoltagePO>> poMap = poList.stream().collect(Collectors.groupingBy(RStatOrgPvVoltagePO::getVoltageClass));
        RStatOrgPvVO result = new RStatOrgPvVO();
        List<RStatOrgPvVO.FlowReversal> flowReversalList = new ArrayList<>();
        List<RStatOrgPvVO.VoltageOutOfLimit> voltageOutOfLimitList = new ArrayList<>();
        List<RStatOrgPvVO.PvPermeability> pvPermeabilityList = new ArrayList<>();
        List<RStatOrgPvVO.LowPowerFactor> lowPowerFactorList = new ArrayList<>();
        poMap.forEach((key, value) -> {
            for (RStatOrgPvVoltagePO po : value) {
                // 潮流倒送
                if (areaPqEventTypeMap.get(po.getAreaPqEventType()).equals(DicDataEnum.EVENT_TYPE_U.getCode())){
                    RStatOrgPvVO.FlowReversal flowReversal = new RStatOrgPvVO.FlowReversal();
                    Integer monitorPointNum = po.getMonitorPointNum();
                    flowReversal.setMonitor(monitorPointNum.toString());
                    flowReversal.setType(key);
                    flowReversalList.add(flowReversal);
                }
                // 电压越限
                if (areaPqEventTypeMap.get(po.getAreaPqEventType()).equals(DicDataEnum.EVENT_TYPE_W.getCode())){
                    RStatOrgPvVO.VoltageOutOfLimit voltageOutOfLimit = new RStatOrgPvVO.VoltageOutOfLimit();
                    Integer monitorPointNum = po.getMonitorPointNum();
                    voltageOutOfLimit.setMonitor(monitorPointNum.toString());
                    voltageOutOfLimit.setType(key);
                    voltageOutOfLimitList.add(voltageOutOfLimit);
                }
                // 渗透率超上限
                if (areaPqEventTypeMap.get(po.getAreaPqEventType()).equals(DicDataEnum.PENET_LIMIT.getCode())){
                    RStatOrgPvVO.PvPermeability pvPermeability = new RStatOrgPvVO.PvPermeability();
                    Integer monitorPointNum = po.getMonitorPointNum();
                    pvPermeability.setMonitor(monitorPointNum.toString());
                    pvPermeability.setType(key);
                    pvPermeabilityList.add(pvPermeability);
                }
                // 低功率因数
                if (areaPqEventTypeMap.get(po.getAreaPqEventType()).equals(DicDataEnum.EVENT_TYPE_I.getCode())){
                    RStatOrgPvVO.LowPowerFactor lowPowerFactor = new RStatOrgPvVO.LowPowerFactor();
                    Integer monitorPointNum = po.getMonitorPointNum();
                    lowPowerFactor.setMonitor(monitorPointNum.toString());
                    lowPowerFactor.setType(key);
                    lowPowerFactorList.add(lowPowerFactor);
                }
            }
        });
        result.setFlowReversal(flowReversalList);
        result.setVoltageOutOfLimit(voltageOutOfLimitList);
        result.setLowPowerFactor(lowPowerFactorList);
        result.setPvPermeability(pvPermeabilityList);
        return result;
    }

    /**
     * 按监测点类型获取分布式光伏总览
     *
     * @param param 条件参数
     * @return com.njcn.common.pojo.response.HttpResult<java.util.List < com.njcn.harmonic.pojo.vo.RMpPvPowerDetailVO>>
     * @author yzh
     * @date 2022/11/24
     */
    @Override
    public RStatOrgPvVO getDistributedPvOverviewLineSort(StatisticsBizBaseParam param) {
        // 获取监测点信息
        List<PwPmsMonitorDTO> monitorDtoList = getMonitorDtoList(param);
        if (CollUtil.isEmpty(monitorDtoList)) {
            return new RStatOrgPvVO();
        }
        // 取出单位
        List<String> deptIds = monitorDtoList.stream().map(PwPmsMonitorDTO::getOrgId).collect(Collectors.toList());
        // 按电压等级获取分布式光伏总览
        LambdaQueryWrapper<RStatOrgPvMonitorTypePO> lqw = new LambdaQueryWrapper<>();
        lqw.in(RStatOrgPvMonitorTypePO::getOrgNo, deptIds);
        lqw.ge(param.getStartTime() != null, RStatOrgPvMonitorTypePO::getDataDate, param.getStartTime());
        lqw.le(param.getEndTime() != null, RStatOrgPvMonitorTypePO::getDataDate, param.getEndTime());
        List<RStatOrgPvMonitorTypePO> poList = rStatOrgPvMonitorTypeService.list(lqw);
        if (CollUtil.isEmpty(poList)) {
            new RStatOrgPvVO();
        }
        // 查询台区电能质量事件类型
        List<DictData> areaPqEventType = dicDataFeignClient
                .getDicDataByTypeCode(DicDataTypeEnum.AREA_PQ_EVENT_TYPE.getCode()).getData();
        // 将事件类型转换成map集合l..
        Map<String, String> areaPqEventTypeMap = areaPqEventType.
                stream().collect(Collectors.toMap(DictData::getId, DictData::getCode));
        // 将查询出来的数据转换成map集合
        Map<String, List<RStatOrgPvMonitorTypePO>> poMap = poList.stream().collect(Collectors.groupingBy(RStatOrgPvMonitorTypePO::getMonitorType));
        RStatOrgPvVO result = new RStatOrgPvVO();
        List<RStatOrgPvVO.FlowReversal> flowReversalList = new ArrayList<>();
        List<RStatOrgPvVO.VoltageOutOfLimit> voltageOutOfLimitList = new ArrayList<>();
        List<RStatOrgPvVO.PvPermeability> pvPermeabilityList = new ArrayList<>();
        List<RStatOrgPvVO.LowPowerFactor> lowPowerFactorList = new ArrayList<>();
        poMap.forEach((key, value) -> {
            for (RStatOrgPvMonitorTypePO po : value) {
                // 潮流倒送
                if (areaPqEventTypeMap.get(po.getAreaPqEventType()).equals(DicDataEnum.EVENT_TYPE_U.getCode())){
                    RStatOrgPvVO.FlowReversal flowReversal = new RStatOrgPvVO.FlowReversal();
                    Integer monitorPointNum = po.getMonitorPointNum();
                    flowReversal.setMonitor(monitorPointNum.toString());
                    flowReversal.setType(key);
                    flowReversalList.add(flowReversal);
                }
                // 电压越限
                if (areaPqEventTypeMap.get(po.getAreaPqEventType()).equals(DicDataEnum.EVENT_TYPE_W.getCode())){
                    RStatOrgPvVO.VoltageOutOfLimit voltageOutOfLimit = new RStatOrgPvVO.VoltageOutOfLimit();
                    Integer monitorPointNum = po.getMonitorPointNum();
                    voltageOutOfLimit.setMonitor(monitorPointNum.toString());
                    voltageOutOfLimit.setType(key);
                    voltageOutOfLimitList.add(voltageOutOfLimit);
                }
                // 渗透率超上限
                if (areaPqEventTypeMap.get(po.getAreaPqEventType()).equals(DicDataEnum.PENET_LIMIT.getCode())){
                    RStatOrgPvVO.PvPermeability pvPermeability = new RStatOrgPvVO.PvPermeability();
                    Integer monitorPointNum = po.getMonitorPointNum();
                    pvPermeability.setMonitor(monitorPointNum.toString());
                    pvPermeability.setType(key);
                    pvPermeabilityList.add(pvPermeability);
                }
                // 低功率因数
                if (areaPqEventTypeMap.get(po.getAreaPqEventType()).equals(DicDataEnum.EVENT_TYPE_I.getCode())){
                    RStatOrgPvVO.LowPowerFactor lowPowerFactor = new RStatOrgPvVO.LowPowerFactor();
                    Integer monitorPointNum = po.getMonitorPointNum();
                    lowPowerFactor.setMonitor(monitorPointNum.toString());
                    lowPowerFactor.setType(key);
                    lowPowerFactorList.add(lowPowerFactor);
                }
            }
        });
        result.setFlowReversal(flowReversalList);
        result.setVoltageOutOfLimit(voltageOutOfLimitList);
        result.setLowPowerFactor(lowPowerFactorList);
        result.setPvPermeability(pvPermeabilityList);
        return result;
    }

    /**
     * 获取监测点信息
     *
     * @param param 条件参数
     */
    private List<PwPmsMonitorDTO> getMonitorDtoList(StatisticsBizBaseParam param) {
        //分布式光伏-（监测店标签-主配网）等演示完更新
        PwPmsMonitorParam pwPmsMonitorParam = new PwPmsMonitorParam();
        pwPmsMonitorParam.setOrgId(param.getId());
        return monitorClient.getPwPhotovoltaicMonitorList(pwPmsMonitorParam).getData();
    }
}
