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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.NumberUtil;
import com.njcn.common.pojo.constant.BizParamConstant;
import com.njcn.device.pms.api.MonitorClient;
import com.njcn.device.pms.api.PmsGeneralDeviceInfoClient;
import com.njcn.device.pms.api.StatationStatClient;
import com.njcn.device.pms.pojo.param.PmsStatationStatInfoParam;
import com.njcn.device.pms.pojo.po.StatationStat;
import com.njcn.event.mapper.majornetwork.RStatEventOrgMapper;
import com.njcn.event.mapper.majornetwork.RStatOrgMapper;
import com.njcn.event.mapper.majornetwork.RStatSubstationMapper;
import com.njcn.event.pojo.param.UniversalFrontEndParam;
import com.njcn.event.pojo.po.RStatEventOrgPO;
import com.njcn.event.pojo.vo.RStatEventOrgVO;
import com.njcn.event.pojo.vo.RStatOrgVO;
import com.njcn.event.pojo.vo.RStatSubstationVO;
import com.njcn.event.service.majornetwork.StatisticsOfTransientIndicatorssService;
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 lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 暂态指标统计
 *
 * @author yzh
 * @date 2022/10/10
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class StatisticsOfTransientIndicatorssServiceImpl implements StatisticsOfTransientIndicatorssService {

    private final RStatOrgMapper rStatOrgMapper;

    private final RStatEventOrgMapper rStatEventOrgMapper;

    private final RStatSubstationMapper rStatSubstationMapper;
    private final DeptFeignClient deptFeignClient;

    private final PmsGeneralDeviceInfoClient pmsGeneralDeviceInfoClient;

    private final DicDataFeignClient dicDataFeignClient;

    private final MonitorClient monitorClient;

    private final StatationStatClient statationStatClient;

    /**
     * 获取区域暂态指标统计
     *
     * @param param 条件参数
     * @return 区域暂态指标统计
     */
    @Override
    public List<RStatOrgVO> getRStatOrg(UniversalFrontEndParam param) {
        //获取所有子部门信息
        List<DeptDTO> deptDTOList = deptFeignClient.getDepSonDetailByDeptId(param.getId()).getData();
        if (CollectionUtil.isEmpty(deptDTOList)) {
            return Collections.emptyList();
        }
        // 取出单位code
        List<String> deptCode = deptDTOList.stream().map(DeptDTO::getCode).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(deptCode)) {
            return Collections.emptyList();
        }
        // 获取主网的id
        String mainnetPointId = getMainnetPointId();
        // 创建返回集合
        List<RStatOrgVO> result = new ArrayList<>();
        // 类型（1年 2季度 3月份 4日
        switch (param.getType().toString()) {
            case BizParamConstant.STAT_BIZ_YEAR:
                // 获取年区域暂态指标统计
                result = rStatOrgMapper.getYearRStatOrgInfo(deptCode, param.getStartTime(), param.getEndTime(), mainnetPointId);
                break;
            case BizParamConstant.STAT_BIZ_QUARTER:
                // 获取季区域暂态指标统计
                result = rStatOrgMapper.getQuarterRStatOrgInfo(deptCode, param.getStartTime(), param.getEndTime(), mainnetPointId);
                break;
            case BizParamConstant.STAT_BIZ_MONTH:
                // 获取月区域暂态指标统计
                result = rStatOrgMapper.getMonthRStatOrgInfo(deptCode, param.getStartTime(), param.getEndTime(), mainnetPointId);
                break;
            default:
                break;
        }
        if (CollUtil.isEmpty(result)) {
            return Collections.emptyList();
        }
        for (RStatOrgVO rStatOrgVO : result) {
            if(rStatOrgVO.getEventMeasurementAverage()!=0&&rStatOrgVO.getEffectiveMeasurementAverage()!=0){
                BigDecimal round = NumberUtil.round(((rStatOrgVO.getEventMeasurementAverage() * 1.0) / (rStatOrgVO.getAllCount() * 1.0)) * 100, 2);
                rStatOrgVO.setEventMeasurementRatioAverage(round.toString());
            }else{
                rStatOrgVO.setEventMeasurementRatioAverage("0");
            }
            if(rStatOrgVO.getEventMeasurementAccrued()!=0&&rStatOrgVO.getEffectiveMeasurementAccrued()!=0){
                BigDecimal round = NumberUtil.round(((rStatOrgVO.getEventMeasurementAccrued() * 1.0) / (rStatOrgVO.getAllCount() * 1.0)) * 100, 2);
                rStatOrgVO.setEventMeasurementRatioAccrued(round.toString());
            }else{
                rStatOrgVO.setEventMeasurementRatioAccrued("0");
            }

        }
        // 匹配单位名称
        Map<String, DeptDTO> deptDTOMap = deptDTOList.stream().collect(Collectors.toMap(DeptDTO::getCode, DeptDTO -> DeptDTO));
        return result.stream().peek(vo -> {
            vo.setOrgName(deptDTOMap.get(vo.getOrgNo()).getName());
            vo.setSort(deptDTOMap.get(vo.getOrgNo()).getSort());
        }).sorted(Comparator.comparing(RStatOrgVO::getSort).reversed()).collect(Collectors.toList());

    }

    /**
     * 获取区域暂态指标分类统计表
     *
     * @param param 条件参数
     * @return 区域暂态指标分类统计表
     */
    @Override
    public List<RStatEventOrgVO> getRStatEventOrg(UniversalFrontEndParam param) {
        //获取所有子部门信息
        List<DeptDTO> deptDTOList = deptFeignClient.getDepSonDetailByDeptId(param.getId()).getData();
        if (CollectionUtil.isEmpty(deptDTOList)) {
            return Collections.emptyList();
        }
        if(CollUtil.isEmpty(param.getMonitorSort())){
            //监测点对象标签
            List<DictData> dataList = dicDataFeignClient.getDicDataByTypeCode(
                    DicDataTypeEnum.MONITORING_LABELS.getCode()).getData();
            param.setMonitorSort(dataList.stream().map(DictData::getId).collect(Collectors.toList()));
        }
        // 取出单位code
        List<String> deptCode = deptDTOList.stream().map(DeptDTO::getCode).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(deptCode)) {
            return Collections.emptyList();
        }
        // 获取主网的id
        String mainnetPointId = getMainnetPointId();
        //创建返回集合
        List<RStatEventOrgVO> result = new ArrayList<>();
        // 创建集合封装查询数据
        List<RStatEventOrgPO> temp = new ArrayList<>();
        // 类型（1年 2季度 3月份 4日
        switch (param.getType().toString()) {
            case BizParamConstant.STAT_BIZ_YEAR:
                // 获取年区域暂态指标分类统计表
                temp = rStatEventOrgMapper.getYearRStatEventOrgInfo(deptCode,param.getMonitorSort(), param.getStartTime(), param.getEndTime(), mainnetPointId);
                break;
            case BizParamConstant.STAT_BIZ_QUARTER:
                // 获取季区域暂态指标分类统计表
                temp = rStatEventOrgMapper.getQuarterRStatEventOrgInfo(deptCode, param.getMonitorSort(),param.getStartTime(), param.getEndTime(), mainnetPointId);
                break;
            case BizParamConstant.STAT_BIZ_MONTH:
                // 获取月区域暂态指标分类统计表
                temp = rStatEventOrgMapper.getMonthRStatEventOrgInfoInfo(deptCode,param.getMonitorSort(), param.getStartTime(), param.getEndTime(), mainnetPointId);
                break;
            default:
                break;
        }
        if (CollUtil.isEmpty(temp)) {
            return Collections.emptyList();
        }
        // 根据暂态指标枚举查询暂态指标
        List<DictData> eventStatis = dicDataFeignClient.getDicDataByTypeCode(
                DicDataTypeEnum.EVENT_STATIS.getCode()).getData();
        // 根据暂态指标code转换成map
        Map<String, DictData> eventStatisMap = eventStatis.stream().collect(Collectors.toMap(DictData::getId, DictData -> DictData));
        // 通过单位code将集合转换为map集合
        Map<String, List<RStatEventOrgPO>> tempMap = temp.stream().collect(Collectors.groupingBy(x->x.getOrgNo()+"_"+x.getMeasurementTypeClass()));
        // 匹配单位名称
        Map<String, DeptDTO> deptDTOMap = deptDTOList.stream().collect(Collectors.toMap(DeptDTO::getCode, DeptDTO -> DeptDTO));
        // 属性赋值
        tempMap.forEach((orgOn, pos) -> {
            RStatEventOrgVO rStatEventOrgVO = new RStatEventOrgVO();
            // 基础属性赋值
            if (rStatEventOrgVO.getOrgNo() == null) {
                String[] split = orgOn.split("_");
                rStatEventOrgVO.setOrgNo(pos.get(0).getOrgNo());
                rStatEventOrgVO.setOrgName(deptDTOMap.get(split[0]).getName());
                rStatEventOrgVO.setDataDate(pos.get(0).getDataDate());
                rStatEventOrgVO.setMonitorType(split[1]);
                rStatEventOrgVO.setEffectiveMeasurementAverage(pos.get(0).getEffectiveMeasurementAverage());
                rStatEventOrgVO.setEffectiveMeasurementAccrued(pos.get(0).getEffectiveMeasurementAccrued());
                rStatEventOrgVO.setEventMeasurementAverage(pos.get(0).getEventMeasurementAverage());
                rStatEventOrgVO.setEventMeasurementAccrued(pos.get(0).getEventMeasurementAccrued());

                if(rStatEventOrgVO.getEventMeasurementAverage()!=0&&rStatEventOrgVO.getEffectiveMeasurementAverage()!=0){
                    double v = (pos.get(0).getEventMeasurementAverage() * 1.0) / (pos.get(0).getEffectiveMeasurementAverage() * 1.0)*100;
                    rStatEventOrgVO.setEventMeasurementRatioAverage(NumberUtil.round(v,2).doubleValue());
                }else{
                    rStatEventOrgVO.setEventMeasurementRatioAverage(0.0);
                }
                if(rStatEventOrgVO.getEventMeasurementAccrued()!=0&&rStatEventOrgVO.getEffectiveMeasurementAccrued()!=0){
                    double v = (pos.get(0).getEventMeasurementAccrued() * 1.0) / (pos.get(0).getEffectiveMeasurementAccrued() * 1.0) * 100;
                    rStatEventOrgVO.setEventMeasurementRatioAccrued(NumberUtil.round(v,2).doubleValue());
                }else{
                    rStatEventOrgVO.setEventMeasurementRatioAccrued(0.0);
                }
                rStatEventOrgVO.setDataType(pos.get(0).getDataType());
            }
            // 暂态指标赋值
            for (RStatEventOrgPO po : pos) {
                String eventStatisCode = eventStatisMap.get(po.getEventType()).getCode();
                if (eventStatisCode.equals(DicDataEnum.SHORT_INTERRUPTIONS.getCode())) {
                    // 日均短时中断
                    rStatEventOrgVO.setDayShortInterruptions(po.getEEventMeasurementAverage());
                    // 累计短时中断
                    rStatEventOrgVO.setCumulativeShortInterruptions(po.getEventMeasurementAccrued());
                    // 日均短时中断占比
                    rStatEventOrgVO.setDayShortInterruptionsProportion(po.getEEventMeasurementRatioAverage());
                    // 累计短时中断占比
                    rStatEventOrgVO.setCumulativeShortInterruptionsProportion(po.getEEventMeasurementRatioAccrued());
                }
                if (eventStatisCode.equals(DicDataEnum.VOLTAGE_RISE.getCode())) {
                    // 日均电压暂升
                    rStatEventOrgVO.setDayVoltageRise(po.getEEventMeasurementAverage());
                    // 累计电压暂升
                    rStatEventOrgVO.setCumulativeVoltageRise(po.getEventMeasurementAccrued());
                    // 日均电压暂升占比
                    rStatEventOrgVO.setDayVoltageRiseProportion(po.getEEventMeasurementRatioAverage());
                    // 累计电压暂升占比
                    rStatEventOrgVO.setCumulativeVoltageRiseProportion(po.getEEventMeasurementRatioAccrued());
                }
                if (eventStatisCode.equals(DicDataEnum.VOLTAGE_DIP.getCode())) {
                    // 日均电压暂降
                    rStatEventOrgVO.setDayVoltageDip(po.getEEventMeasurementAverage());
                    // 累计电压暂降
                    rStatEventOrgVO.setCumulativeVoltageDip(po.getEventMeasurementAccrued());
                    // 日均电压暂降占比
                    rStatEventOrgVO.setDayVoltageDipProportion(po.getEEventMeasurementRatioAverage());
                    // 累计电压暂降占比
                    rStatEventOrgVO.setCumulativeVoltageDipProportion(po.getEEventMeasurementRatioAccrued());
                }
            }
            result.add(rStatEventOrgVO);
        });
        if(CollUtil.isNotEmpty(result)){
            result.sort(Comparator.comparing(x->x.getOrgName()));
        }
        return result;
    }

    /**
     * 获取变电站暂态指标分类统计表
     *
     * @param param 前端传入参数
     * @return 变电站暂态指标分类统计表
     */
    @Override
    public List<RStatSubstationVO> getRStatSubstation(UniversalFrontEndParam param) {
        //获取所有子部门信息
        List<DeptDTO> deptDTOList = deptFeignClient.getDeptDescendantIndexes(param.getId(), WebUtil.filterDeptType()).getData();
        if (CollectionUtil.isEmpty(deptDTOList)) {
            return Collections.emptyList();
        }
        // 取出单位code
        List<String> deptCode = deptDTOList.stream().map(DeptDTO::getCode).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(deptCode)) {
            return Collections.emptyList();
        }

        // 查询变电站信息
        PmsStatationStatInfoParam pmsStatationStatInfoParam = new PmsStatationStatInfoParam();
        pmsStatationStatInfoParam.setOrgIds(deptCode);
        if (!StringUtils.isEmpty(param.getSubName())) {
            pmsStatationStatInfoParam.setPowerName(param.getSubName());
        }
        List<StatationStat> powerInfo = statationStatClient.getPowerInfo(pmsStatationStatInfoParam).getData();
        if (CollUtil.isEmpty(powerInfo)) {
            return Collections.emptyList();
        }

        // 取出变电站id
        List<String> powerIds = powerInfo.stream().map(StatationStat::getPowerId).collect(Collectors.toList());
        //创建返回集合
        List<RStatSubstationVO> result = new ArrayList<>();

        // 类型（1年 2季度 3月份 4日
        switch (param.getType().toString()) {
            case BizParamConstant.STAT_BIZ_YEAR:
                // 获取年变电站暂态指标分类统计表
                result = rStatSubstationMapper.getYearInfo(powerIds, param.getStartTime(), param.getEndTime());
                break;
            case BizParamConstant.STAT_BIZ_QUARTER:
                // 获取季变电站暂态指标分类统计表
                result = rStatSubstationMapper.getQuarterInfo(powerIds, param.getStartTime(), param.getEndTime());
                break;
            case BizParamConstant.STAT_BIZ_MONTH:
                // 获取月变电站暂态指标分类统计表
                result = rStatSubstationMapper.getMonthInfo(powerIds, param.getStartTime(), param.getEndTime());
                break;
            default:
                break;
        }
        if (CollUtil.isEmpty(result)) {
            return Collections.emptyList();
        }
        // 将变电站信息根据变电站id转换成map集合
        Map<String, StatationStat> powerMap = powerInfo.stream().collect(Collectors.toMap(StatationStat::getPowerId, StatationStat -> StatationStat));
        // 属性赋值
        List<RStatSubstationVO> collect = result.stream().peek(vo -> {
            String substationId = vo.getSubstationId();
            vo.setDeptId(powerMap.get(substationId).getOrgId());
            vo.setSubstationName(powerMap.get(substationId).getPowerName());
            String deptId = vo.getDeptId();
            for (DeptDTO deptDTO : deptDTOList) {
                if (deptId.equals(deptDTO.getCode())) {
                    vo.setDeptName(deptDTO.getName());
                    vo.setSort(deptDTO.getSort());
                }
            }
        }).collect(Collectors.toList());
        if (CollUtil.isEmpty(collect)){
            collect.sort(Comparator.comparing(RStatSubstationVO::getSort).reversed());
        }
        return collect;
    }


    /**
     * 获取主网的id
     *
     * @return java.lang.String
     * @author yzh
     * @date 2022/10/31
     */
    private String getMainnetPointId() {
        return dicDataFeignClient.getDicDataByCode(DicDataEnum.MAINNET_POINT.getCode()).getData().getId();
    }
}





