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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.njcn.common.pojo.param.StatisticsBizBaseParam;
import com.njcn.harmonic.pojo.param.RStatHarmonicMParam;
import com.njcn.harmonic.pojo.po.RStatHarmonicOrgQ;
import com.njcn.harmonic.mapper.StatHarmonicOrgQMapper;
import com.njcn.harmonic.pojo.vo.RArrayVO;
import com.njcn.harmonic.pojo.vo.RIconVO;
import com.njcn.harmonic.pojo.vo.RStatHarmonicMVO;
import com.njcn.harmonic.service.majornetwork.RStatHarmonicOrgQService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.harmonic.utils.DeptUtil;
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.utils.WebUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author rui.wu
 * @since 2022-10-14
 */
@Service
@RequiredArgsConstructor
public class RStatHarmonicOrgQServiceImpl extends ServiceImpl<StatHarmonicOrgQMapper, RStatHarmonicOrgQ> implements RStatHarmonicOrgQService {

    private final DeptFeignClient deptFeignClient;
    private final DicDataFeignClient dicDataFeignClient;
    private final StatHarmonicOrgQMapper statHarmonicOrgQMapper;

    @Override
    public List<RArrayVO> getRStatHarmonicQAll(StatisticsBizBaseParam param) {
        //对象主节点 获取所有的稳态类型
        List<DictData> steadyData = dicDataFeignClient.getDicDataByTypeCode(
                DicDataTypeEnum.STEADY_STATIS.getCode()).getData();
        Map<String, DictData> steadyMap = steadyData.stream()
                .collect(Collectors.toMap(DictData::getId, Function.identity()));

        //子节点 获取所有得各单位类型
        List<DeptDTO> deptList = deptFeignClient.getDeptDescendantIndexes(param.getId(), WebUtil.filterDeptType()).getData();
        List<DeptDTO> deptDTOList = DeptUtil.getDeptSubsetVOList(deptList, param.getId());

        //获取部门id集合
        List<String> deptIds = deptDTOList.stream().map(DeptDTO::getCode).collect(Collectors.toList());
        Map<String, DeptDTO> deptMap = deptDTOList.stream().collect(Collectors.toMap(DeptDTO::getCode, Function.identity()));

        //获取配网信息
        DictData mainnetData = dicDataFeignClient.getDicDataByCode(DicDataEnum.MAINNET_POINT.getCode()).getData();
        //初始化指标类型（横向）
        List<RArrayVO> arrayVOList = new ArrayList<>();
        //数据库查询
        List<RStatHarmonicOrgQ> list = statHarmonicOrgQMapper.selectList(new LambdaQueryWrapper<RStatHarmonicOrgQ>()
                .eq(RStatHarmonicOrgQ::getDataType, mainnetData.getId())
                .in(RStatHarmonicOrgQ::getOrgNo, deptIds)
                .ge(StrUtil.isNotBlank(param.getStartTime()), RStatHarmonicOrgQ::getDataDate, param.getStartTime())
                .le(StrUtil.isNotBlank(param.getEndTime()), RStatHarmonicOrgQ::getDataDate, param.getEndTime()));
        //根据稳态指标分组
        Map<String, List<RStatHarmonicOrgQ>> measurementMap = list.stream().collect(Collectors.groupingBy(RStatHarmonicOrgQ::getHarmonicType));
        //判断对象是否为空
        if (CollUtil.isNotEmpty(list)) {
            //重新生成数据结构
            measurementMap.forEach((key, value) -> {
                List<RStatHarmonicMVO> eventVO = new ArrayList<>();
                if (steadyMap.containsKey(key)) {
                    RArrayVO arrayVO = new RArrayVO();
                    DictData data = steadyMap.get(key);
                    arrayVO.setRowName(data.getName());
                    arrayVO.setSort(data.getSort());
                    for (RStatHarmonicOrgQ statHarmonic : value) {
                        if (deptMap.containsKey(statHarmonic.getOrgNo())) {
                            RStatHarmonicMVO r = BeanUtil.copyProperties(statHarmonic, RStatHarmonicMVO.class);
                            DeptDTO deptDTO = deptMap.get(statHarmonic.getOrgNo());
                            r.setHarmonicName(deptDTO.getName());
                            r.setSort(deptDTO.getSort());
                            eventVO.add(r);
                        }

                    }
                    //根据监测点类别获取差集
                    Map<String, List<RStatHarmonicOrgQ>> listMap = value.stream().collect(Collectors.groupingBy(RStatHarmonicOrgQ::getOrgNo));
                    List<DeptDTO> notDeptDTOS = deptDTOList.stream().filter(r -> !listMap.containsKey(r.getCode()))
                            .collect(Collectors.toList());
                    this.assignDict(notDeptDTOS, eventVO, arrayVO);
                    eventVO.sort(Comparator.comparing(statHarmonic -> statHarmonic.getSort()));
                    arrayVOList.add(arrayVO);
                }
            });
        }
        //处理主节点不存在的集合
        List<DictData> notMeasurementList = steadyData.stream().filter(r -> !measurementMap.containsKey(r.getId()))
                .collect(Collectors.toList());
        for (DictData notData : notMeasurementList) {
            List<RStatHarmonicMVO> statharmonicVO = new ArrayList<>();
            RArrayVO arrayVO = new RArrayVO();
            arrayVO.setRowName(notData.getName());
            arrayVO.setSort(notData.getSort());
            this.assignDict(deptDTOList, statharmonicVO, arrayVO);
            statharmonicVO.sort(Comparator.comparing(statHarmonic -> statHarmonic.getSort()));
            arrayVOList.add(arrayVO);
        }
        arrayVOList.sort(Comparator.comparing(rArrayVO -> rArrayVO.getSort()));
        return arrayVOList;
    }

    @Override
    public List<RIconVO> getRStatHarmonicOrgQIcon(RStatHarmonicMParam param) {
        //子节点 获取所有得各单位类型
        List<DeptDTO> deptList = deptFeignClient.getDeptDescendantIndexes(param.getId(), WebUtil.filterDeptType()).getData();
        List<DeptDTO> deptDTOList = DeptUtil.getDeptSubsetVOList(deptList, param.getId());

        Map<String, DeptDTO> deptMap = deptDTOList.stream().collect(Collectors.toMap(DeptDTO::getCode, Function.identity()));
        //获取部门id集合
        List<String> deptIds = deptDTOList.stream().map(DeptDTO::getCode).collect(Collectors.toList());
        //指标对象类型属性
        DictData harmonicData;
        //判断是是否传入检测点信息值（电压）
        if (StrUtil.isBlank(param.getStasisID()) && StrUtil.isBlank(param.getMonitorID())) {
            //指标对象类型
            List<DictData> indicatorTypeDate = dicDataFeignClient.getDicDataByTypeCode(
                    DicDataTypeEnum.STEADY_STATIS.getCode()).getData();
            indicatorTypeDate.sort(Comparator.comparing(data -> data.getSort()));
            harmonicData = indicatorTypeDate.get(0);
        } else {
            //获取指标对象（频率偏差）
            harmonicData = dicDataFeignClient.getDicDataById(
                    param.getStasisID()).getData();
        }
        //反防止参数查询数据报错
        Assert.isTrue(
                CollUtil.isNotEmpty(deptDTOList) || ObjectUtil.isNotNull(harmonicData)
                , "各单位或者指标类型为空,请检查入参是否准确");
        //获取主网id信息
        DictData mainnetData = dicDataFeignClient.getDicDataByCode(DicDataEnum.MAINNET_POINT.getCode()).getData();

        //初始化对象
        List<RIconVO> arrayVOList = new ArrayList<>();
        List<RStatHarmonicOrgQ> rStatHarmonicVoltageMS = statHarmonicOrgQMapper.selectList(new LambdaQueryWrapper<RStatHarmonicOrgQ>()
                .eq(RStatHarmonicOrgQ::getDataType, mainnetData.getId())
                .in(RStatHarmonicOrgQ::getOrgNo, deptIds)
                .eq(RStatHarmonicOrgQ::getHarmonicType, harmonicData.getId())
                .ge(StrUtil.isNotBlank(param.getStartTime()), RStatHarmonicOrgQ::getDataDate, param.getStartTime())
                .le(StrUtil.isNotBlank(param.getEndTime()), RStatHarmonicOrgQ::getDataDate, param.getEndTime())
        );
        //将数据转换为map进行便利
        Map<String, List<RStatHarmonicOrgQ>> voltageMMap = rStatHarmonicVoltageMS.stream()
                .collect(Collectors.groupingBy(RStatHarmonicOrgQ::getOrgNo));
        //对象
        if (CollUtil.isNotEmpty(rStatHarmonicVoltageMS)) {
            voltageMMap.forEach((key, value) -> {
                if (deptMap.containsKey(key)) {
                    DeptDTO data = deptMap.get(key);
                    for (RStatHarmonicOrgQ orgQ : value) {
                        RIconVO rIconVO = new RIconVO();
                        rIconVO.setRowName(data.getName());
                        rIconVO.setSort(data.getSort());
                        rIconVO.setOverLimitMeasurementAccrued(orgQ.getOverLimitMeasurementAccrued());
                        rIconVO.setOverLimitMeasurementAverage(orgQ.getOverLimitMeasurementAverage());
                        rIconVO.setOverLimitMeasurementRatioAccrued(orgQ.getOverLimitMeasurementRatioAccrued());
                        rIconVO.setOverLimitMeasurementRatioAverage(orgQ.getOverLimitMeasurementRatioAverage());
                        rIconVO.setAverageOverDay(orgQ.getAverageOverDay());
                        arrayVOList.add(rIconVO);
                    }

                }
            });
        }
        //处理主节点不存在的集合
        List<DeptDTO> notMeasurementList = deptDTOList.stream().filter(r -> !voltageMMap.containsKey(r.getCode()))
                .collect(Collectors.toList());
        for (DeptDTO notData : notMeasurementList) {
            RIconVO iconVO = new RIconVO();
            iconVO.setRowName(notData.getName());
            iconVO.setSort(notData.getSort());
            iconVO.setOverLimitMeasurementAverage(0.0F);
            iconVO.setOverLimitMeasurementAccrued(0);
            iconVO.setOverLimitMeasurementRatioAverage(0.0F);
            iconVO.setOverLimitMeasurementRatioAccrued(0.0F);
            iconVO.setAverageOverDay(0.0F);
            arrayVOList.add(iconVO);
        }
        arrayVOList.sort(Comparator.comparing(rIconVO -> rIconVO.getSort()));
        return arrayVOList;
    }

    @Override
    public List<RArrayVO> getPwRStatHarmonicQAll(StatisticsBizBaseParam param) {
        //对象主节点 获取所有的稳态类型
        List<DictData> steadyData = dicDataFeignClient.getDicDataByTypeCode(
                DicDataTypeEnum.STEADY_STATIS.getCode()).getData();
        Map<String, DictData> steadyMap = steadyData.stream()
                .collect(Collectors.toMap(DictData::getId, Function.identity()));

        //子节点 获取所有得各单位类型
        List<DeptDTO> deptList = deptFeignClient.getDeptDescendantIndexes(param.getId(), WebUtil.filterDeptType()).getData();
        List<DeptDTO> deptDTOList = DeptUtil.getDeptSubsetVOList(deptList, param.getId());

        //获取部门id集合
        List<String> deptIds = deptDTOList.stream().map(DeptDTO::getCode).collect(Collectors.toList());
        Map<String, DeptDTO> deptMap = deptDTOList.stream().collect(Collectors.toMap(DeptDTO::getCode, Function.identity()));

        //获取配网信息
        DictData distributionData = dicDataFeignClient.getDicDataByCode(DicDataEnum.DISTRIBUTION_POINT.getCode()).getData();
        //初始化指标类型（横向）
        List<RArrayVO> arrayVOList = new ArrayList<>();
        //数据库查询
        List<RStatHarmonicOrgQ> list = statHarmonicOrgQMapper.selectList(new LambdaQueryWrapper<RStatHarmonicOrgQ>()
                .eq(RStatHarmonicOrgQ::getDataType, distributionData.getId())
                .in(RStatHarmonicOrgQ::getOrgNo, deptIds)
                .ge(StrUtil.isNotBlank(param.getStartTime()), RStatHarmonicOrgQ::getDataDate, param.getStartTime())
                .le(StrUtil.isNotBlank(param.getEndTime()), RStatHarmonicOrgQ::getDataDate, param.getEndTime()));
        //根据稳态指标分组
        Map<String, List<RStatHarmonicOrgQ>> measurementMap = list.stream().collect(Collectors.groupingBy(RStatHarmonicOrgQ::getHarmonicType));
        //判断对象是否为空
        if (CollUtil.isNotEmpty(list)) {
            //重新生成数据结构
            measurementMap.forEach((key, value) -> {
                List<RStatHarmonicMVO> eventVO = new ArrayList<>();
                if (steadyMap.containsKey(key)) {
                    RArrayVO arrayVO = new RArrayVO();
                    DictData data = steadyMap.get(key);
                    arrayVO.setRowName(data.getName());
                    arrayVO.setSort(data.getSort());
                    for (RStatHarmonicOrgQ statHarmonic : value) {
                        if (deptMap.containsKey(statHarmonic.getOrgNo())) {
                            RStatHarmonicMVO r = BeanUtil.copyProperties(statHarmonic, RStatHarmonicMVO.class);
                            DeptDTO deptDTO = deptMap.get(statHarmonic.getOrgNo());
                            r.setHarmonicName(deptDTO.getName());
                            r.setSort(deptDTO.getSort());
                            eventVO.add(r);
                        }

                    }
                    //根据监测点类别获取差集
                    Map<String, List<RStatHarmonicOrgQ>> listMap = value.stream().collect(Collectors.groupingBy(RStatHarmonicOrgQ::getOrgNo));
                    List<DeptDTO> notDeptDTOS = deptDTOList.stream().filter(r -> !listMap.containsKey(r.getCode()))
                            .collect(Collectors.toList());
                    this.assignDict(notDeptDTOS, eventVO, arrayVO);
                    eventVO.sort(Comparator.comparing(statHarmonic -> statHarmonic.getSort()));
                    arrayVOList.add(arrayVO);
                }
            });
        }
        //处理主节点不存在的集合
        List<DictData> notMeasurementList = steadyData.stream().filter(r -> !measurementMap.containsKey(r.getId()))
                .collect(Collectors.toList());
        for (DictData notData : notMeasurementList) {
            List<RStatHarmonicMVO> statharmonicVO = new ArrayList<>();
            RArrayVO arrayVO = new RArrayVO();
            arrayVO.setRowName(notData.getName());
            arrayVO.setSort(notData.getSort());
            this.assignDict(deptDTOList, statharmonicVO, arrayVO);
            statharmonicVO.sort(Comparator.comparing(statHarmonic -> statHarmonic.getSort()));
            arrayVOList.add(arrayVO);
        }
        arrayVOList.sort(Comparator.comparing(rArrayVO -> rArrayVO.getSort()));
        return arrayVOList;
    }

    @Override
    public List<RIconVO> getPwRStatHarmonicOrgQIcon(RStatHarmonicMParam param) {
        //各单位类型
        List<DeptDTO> deptList = deptFeignClient.getDeptDescendantIndexes(param.getId(), WebUtil.filterDeptType()).getData();
        List<DeptDTO> deptDTOList = DeptUtil.getDeptSubsetVOList(deptList, param.getId());

        Map<String, DeptDTO> deptMap = deptDTOList.stream().collect(Collectors.toMap(DeptDTO::getCode, Function.identity()));
        //获取部门id集合
        List<String> deptIds = deptDTOList.stream().map(DeptDTO::getCode).collect(Collectors.toList());
        //指标对象类型属性
        DictData harmonicData;
        //判断是是否传入检测点信息值（电压）
        if (StrUtil.isBlank(param.getStasisID()) && StrUtil.isBlank(param.getMonitorID())) {
            //指标对象类型
            List<DictData> indicatorTypeDate = dicDataFeignClient.getDicDataByTypeCode(
                    DicDataTypeEnum.STEADY_STATIS.getCode()).getData();
            indicatorTypeDate.sort(Comparator.comparing(data -> data.getSort()));
            harmonicData = indicatorTypeDate.get(0);
        } else {
            //获取指标对象（频率偏差）
            harmonicData = dicDataFeignClient.getDicDataById(
                    param.getStasisID()).getData();
        }
        //反防止参数查询数据报错
        Assert.isTrue(
                CollUtil.isNotEmpty(deptDTOList) || ObjectUtil.isNotNull(harmonicData)
                , "各单位或者指标类型为空,请检查入参是否准确");
        //获取配网信息
        DictData distributionData = dicDataFeignClient.getDicDataByCode(DicDataEnum.DISTRIBUTION_POINT.getCode()).getData();

        //初始化对象
        List<RIconVO> arrayVOList = new ArrayList<>();
        List<RStatHarmonicOrgQ> rStatHarmonicVoltageMS = statHarmonicOrgQMapper.selectList(new LambdaQueryWrapper<RStatHarmonicOrgQ>()
                .eq(RStatHarmonicOrgQ::getDataType, distributionData.getId())
                .in(RStatHarmonicOrgQ::getOrgNo, deptIds)
                .eq(RStatHarmonicOrgQ::getHarmonicType, harmonicData.getId())
                .ge(StrUtil.isNotBlank(param.getStartTime()), RStatHarmonicOrgQ::getDataDate, param.getStartTime())
                .le(StrUtil.isNotBlank(param.getEndTime()), RStatHarmonicOrgQ::getDataDate, param.getEndTime())
        );
        //将数据转换为map进行便利
        Map<String, List<RStatHarmonicOrgQ>> voltageMMap = rStatHarmonicVoltageMS.stream()
                .collect(Collectors.groupingBy(RStatHarmonicOrgQ::getOrgNo));
        //对象
        if (CollUtil.isNotEmpty(rStatHarmonicVoltageMS)) {
            voltageMMap.forEach((key, value) -> {
                if (deptMap.containsKey(key)) {
                    DeptDTO data = deptMap.get(key);
                    for (RStatHarmonicOrgQ orgQ : value) {
                        RIconVO rIconVO = new RIconVO();
                        rIconVO.setRowName(data.getName());
                        rIconVO.setSort(data.getSort());
                        rIconVO.setOverLimitMeasurementAccrued(orgQ.getOverLimitMeasurementAccrued());
                        rIconVO.setOverLimitMeasurementAverage(orgQ.getOverLimitMeasurementAverage());
                        rIconVO.setOverLimitMeasurementRatioAccrued(orgQ.getOverLimitMeasurementRatioAccrued());
                        rIconVO.setOverLimitMeasurementRatioAverage(orgQ.getOverLimitMeasurementRatioAverage());
                        rIconVO.setAverageOverDay(orgQ.getAverageOverDay());
                        arrayVOList.add(rIconVO);
                    }

                }
            });
        }
        //处理主节点不存在的集合
        List<DeptDTO> notMeasurementList = deptDTOList.stream().filter(r -> !voltageMMap.containsKey(r.getCode()))
                .collect(Collectors.toList());
        for (DeptDTO notData : notMeasurementList) {
            RIconVO iconVO = new RIconVO();
            iconVO.setRowName(notData.getName());
            iconVO.setSort(notData.getSort());
            iconVO.setOverLimitMeasurementAverage(0.0F);
            iconVO.setOverLimitMeasurementAccrued(0);
            iconVO.setOverLimitMeasurementRatioAverage(0.0F);
            iconVO.setOverLimitMeasurementRatioAccrued(0.0F);
            iconVO.setAverageOverDay(0.0F);
            arrayVOList.add(iconVO);
        }
        arrayVOList.sort(Comparator.comparing(rIconVO -> rIconVO.getSort()));
        return arrayVOList;
    }

    /**
     * 便利赋值
     *
     * @param deptDTOList    部门信息集合
     * @param statharmonicVO 暂态监测点
     * @param arrayVO        初始化对象
     */
    private void assignDict(List<DeptDTO> deptDTOList, List<RStatHarmonicMVO> statharmonicVO, RArrayVO arrayVO) {
        for (DeptDTO dictData : deptDTOList) {
            RStatHarmonicMVO notStatHarmonicVO = new RStatHarmonicMVO();
            notStatHarmonicVO.setHarmonicName(dictData.getName());
            notStatHarmonicVO.setSort(dictData.getSort());
            notStatHarmonicVO.setOverLimitMeasurementAverage(0.0F);
            notStatHarmonicVO.setOverLimitMeasurementAccrued(0);
            notStatHarmonicVO.setOverDay(0);
            notStatHarmonicVO.setOverLimitMeasurementRatioAverage(0.0F);
            notStatHarmonicVO.setOverLimitMeasurementRatioAccrued(0.0F);
            notStatHarmonicVO.setAverageOverDay(0.0F);
            statharmonicVO.add(notStatHarmonicVO);
        }
        arrayVO.setColumns(statharmonicVO);
    }
}
