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

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njcn.common.pojo.constant.BizParamConstant;
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.event.mapper.distribution.PwRStatOrgClassifiedMapper;
import com.njcn.event.mapper.distribution.PwRStatOrgMapper;
import com.njcn.event.pojo.param.PwUniversalFrontEndParam;
import com.njcn.event.pojo.po.RStatEventOrgPO;
import com.njcn.event.pojo.po.RStatOrgPO;
import com.njcn.event.pojo.vo.PwRStatEventOrgVO;
import com.njcn.event.pojo.vo.RStatOrgVO;
import com.njcn.event.service.distribution.PwRStatOrgService;
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 lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 配网-暂态事件统计
 *
 * @author yzh
 * @date 2022/10/24
 */

@Service
@Slf4j
@RequiredArgsConstructor
public class PwRStatOrgServiceImpl implements PwRStatOrgService {

    private final PwMonitorClient monitorClient;

    private final DicDataFeignClient dicDataFeignClient;

    private final PwRStatOrgMapper pwRStatOrgMapper;

    private final PwRStatOrgClassifiedMapper pwRStatOrgClassifiedMapper;

    private final DeptFeignClient deptFeignClient;

    private final DecimalFormat df = new DecimalFormat("###.00");

    /**
     * 获取配网区域暂态指标统计
     *
     * @param param 前端传入参数
     * @return 配网区域暂态指标统计
     */
    @Override
    public List<RStatOrgVO> getPwRStatOrg(PwUniversalFrontEndParam param) {
        // 获取单位下的监测点id集合
        List<DeptDTO> deptDTOList = deptFeignClient.getDepSonDetailByDeptId(param.getId()).getData();
        Map<String,DeptDTO> map = deptDTOList.stream().collect(Collectors.toMap(DeptDTO::getCode, Function.identity()));

        // 查询字典表
        List<DictData> dictDataList = dicDataFeignClient
                .getDicDataByTypeCode(DicDataTypeEnum.LINE_SORT.getCode())
                .getData();
        // 取出单位id
        List<String> deptIdList = deptDTOList.stream().map(DeptDTO::getCode).collect(Collectors.toList());
        // 获取配网id
        String distributionPoint = getDistributionPoint();
        // 创建集合封装查询数据
        List<RStatOrgPO> rStatOrgPO = new ArrayList<>();
        // 判断条件
        switch (param.getType().toString()) {
            // 年
            case BizParamConstant.STAT_BIZ_YEAR:
                rStatOrgPO = pwRStatOrgMapper.getYearInfo(
                        deptIdList,
                        param.getStartTime(),
                        param.getEndTime(),
                        distributionPoint);
                break;
            // 季
            case BizParamConstant.STAT_BIZ_QUARTER:
                rStatOrgPO = pwRStatOrgMapper.getQuarterInfo(
                        deptIdList,
                        param.getStartTime(),
                        param.getEndTime(),
                        distributionPoint);
                break;
            // 月
            case BizParamConstant.STAT_BIZ_MONTH:
                rStatOrgPO = pwRStatOrgMapper.getMonthInfo(
                        deptIdList,
                        param.getStartTime(),
                        param.getEndTime(),
                        distributionPoint);
                break;
            default:
                break;
        }
        if (CollUtil.isEmpty(rStatOrgPO)) {
            return Collections.emptyList();
        }
        // 数据处理
        return rStatOrgPO.stream().map(po -> {
            RStatOrgVO vo = new RStatOrgVO();
            BeanUtils.copyProperties(po, vo);
            if(map.containsKey(po.getOrgNo())){
                DeptDTO dto = map.get(po.getOrgNo());
                vo.setOrgName(dto.getName());
                for (DictData dictData : dictDataList) {
                    if (po.getMeasurementTypeClass().equals(dictData.getId())) {
                        vo.setMonitorSort(dictData.getName());
                        if (dictData.getCode().equals(DicDataEnum.ONE_LINE.getCode())) {
                            vo.setEventMeasurementRatioAverage(df.format(((po.getEventMeasurementAverage() * 1.0) / (po.getEffectiveMeasurementAverage() * 1.0)) * 100));
                            vo.setEventMeasurementRatioAccrued(df.format(((po.getEventMeasurementAccrued() * 1.0) / (po.getEffectiveMeasurementAccrued() * 1.0)) * 100));
                            vo.setEventFreq(po.getEventFreq().toString());
                        } else {
                            vo.setEventMeasurementRatioAverage("/");
                            vo.setEventMeasurementRatioAccrued("/");
                            vo.setEventFreq("/");
                        }
                    }
                }
            }


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

    /**
     * 获取配网区域暂态事件分类统计
     *
     * @param param 前端传入参数
     * @return 配网区域暂态事件分类统计
     */
    @Override
    public List<PwRStatEventOrgVO> getPwRStatOrgClassified(PwUniversalFrontEndParam param) {
        List<DeptDTO> deptDTOList = deptFeignClient.getDepSonDetailByDeptId(param.getId()).getData();
        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()));
        }
        // 创建集合封装返回数据
        List<PwRStatEventOrgVO> result = new ArrayList<>();
        // 取出单位id
        List<String> deptIdList = deptDTOList.stream().map(DeptDTO::getCode).collect(Collectors.toList());
        // 创建集合封装查询数据
        List<RStatEventOrgPO> rStatEventOrgVOList = new ArrayList<>();
        // 获取配网id
        String distributionPoint = getDistributionPoint();
        // 判断条件
        switch (param.getType().toString()) {
            // 年
            case BizParamConstant.STAT_BIZ_YEAR:
                rStatEventOrgVOList = pwRStatOrgClassifiedMapper.getYearInfo(
                        deptIdList,
                        param.getMonitorSort(),
                        param.getStartTime(),
                        param.getEndTime(),
                        distributionPoint);
                break;
            // 季
            case BizParamConstant.STAT_BIZ_QUARTER:
                rStatEventOrgVOList = pwRStatOrgClassifiedMapper.getQuarterInfo(
                        deptIdList,
                        param.getMonitorSort(),
                        param.getStartTime(),
                        param.getEndTime(),
                        distributionPoint);
                break;
            // 月
            case BizParamConstant.STAT_BIZ_MONTH:
                rStatEventOrgVOList = pwRStatOrgClassifiedMapper.getMonthInfo(
                        deptIdList,
                        param.getMonitorSort(),
                        param.getStartTime(),
                        param.getEndTime(),
                        distributionPoint);
                break;
            default:
                break;
        }
        if (CollUtil.isEmpty(rStatEventOrgVOList)) {
            return Collections.emptyList();
        }
        // 查询监测点类别字典表
        List<DictData> lineSortList = dicDataFeignClient
                .getDicDataByTypeCode(DicDataTypeEnum.LINE_SORT.getCode())
                .getData();
        // 查询暂态指标字典表
        List<DictData> eventStatisList = dicDataFeignClient
                .getDicDataByTypeCode(DicDataTypeEnum.EVENT_STATIS.getCode())
                .getData();
        // 将查询出的数据转为map集合
        Map<String, List<RStatEventOrgPO>> rStatEventOrgVOMap = rStatEventOrgVOList.stream().collect(Collectors.groupingBy(RStatEventOrgPO::getOrgNo));
        // 蒋监测点类别字典表转换成map集合
        Map<String, DictData> lineSortMap = lineSortList.stream().collect(Collectors.toMap(DictData::getId, DictData -> DictData));
        // 根据暂态指标code转换成map
        Map<String, DictData> eventStatisMap = eventStatisList.stream().collect(Collectors.toMap(DictData::getId, DictData -> DictData));

        // 数据处理
        Map<String,DeptDTO> map = deptDTOList.stream().collect(Collectors.toMap(DeptDTO::getCode, Function.identity()));
        rStatEventOrgVOMap.forEach((orgOn, pos) -> {
            PwRStatEventOrgVO vo = new PwRStatEventOrgVO();
            // 基础属性赋值
            if (vo.getOrgNo() == null) {
                vo.setOrgNo(pos.get(0).getOrgNo());
                vo.setOrgName(map.get(orgOn).getName());
                vo.setDataDate(pos.get(0).getDataDate());
                vo.setMeasurementTypeClass(pos.get(0).getMeasurementTypeClass());
                vo.setEffectiveMeasurementAverage(pos.get(0).getEffectiveMeasurementAverage());
                vo.setEffectiveMeasurementAccrued(pos.get(0).getEffectiveMeasurementAccrued());
                vo.setEventMeasurementAverage(pos.get(0).getEventMeasurementAverage());
                vo.setEventMeasurementAccrued(pos.get(0).getEventMeasurementAccrued());
                vo.setEventCount(pos.get(0).getEventCount());
                vo.setEventFreq(pos.get(0).getEEventFreq());
                vo.setDataType(pos.get(0).getDataType());
            }
            for (RStatEventOrgPO po : pos) {
                // 取出监测点类别
                String measurementTypeClass = po.getMeasurementTypeClass();
                // 取出暂态指标id
                String eventType = po.getEventType();
                // 取出监测点类别code
                String lineSortCode = lineSortMap.get(measurementTypeClass).getCode();
                // 取出暂态指标code
                String eventStatisCode = eventStatisMap.get(eventType).getCode();
                vo.setMeasurementTypeClass(lineSortMap.get(measurementTypeClass).getName());
                if (lineSortCode.equals(DicDataEnum.ONE_LINE.getCode())) {
                    vo.setEventMeasurementRatioAverage(Double.parseDouble(df.format(
                            (po.getEventMeasurementAverage() * 1.0) / (po.getEffectiveMeasurementAverage() * 1.0))) * 100);
                    vo.setEventMeasurementRatioAccrued(Double.parseDouble(df.format(
                            (po.getEventMeasurementAccrued() * 1.0) / (po.getEffectiveMeasurementAccrued() * 1.0))) * 100);
                }
                if (eventStatisCode.equals(DicDataEnum.SHORT_INTERRUPTIONS.getCode())) {
                    // 日均短时中断
                    vo.setDayShortInterruptions(po.getEEventMeasurementAverage());
                    // 累计短时中断
                    vo.setCumulativeShortInterruptions(po.getEventMeasurementAccrued());
                    if (lineSortCode.equals(DicDataEnum.ONE_LINE.getCode())) {
                        // 日均短时中断占比
                        vo.setDayShortInterruptionsProportion(po.getEEventMeasurementRatioAverage());
                        // 累计短时中断占比
                        vo.setCumulativeShortInterruptionsProportion(po.getEEventMeasurementRatioAccrued());
                        vo.setShortInterruptionsFreq(po.getEEventFreq());
                        vo.setShortInterruptionsCount(po.getEEventCount());
                    }
                }
                if (eventStatisCode.equals(DicDataEnum.VOLTAGE_RISE.getCode())) {
                    // 日均电压暂升
                    vo.setDayVoltageRise(po.getEEventMeasurementAverage());
                    // 累计电压暂升
                    vo.setCumulativeVoltageRise(po.getEventMeasurementAccrued());
                    if (lineSortCode.equals(DicDataEnum.ONE_LINE.getCode())) {
                        // 日均电压暂升占比
                        vo.setDayVoltageRiseProportion(po.getEEventMeasurementRatioAverage());
                        // 累计电压暂升占比
                        vo.setCumulativeVoltageRiseProportion(po.getEEventMeasurementRatioAccrued());
                        vo.setVoltageRiseFreq(po.getEEventFreq());
                        vo.setVoltageRiseCount(po.getEEventCount());
                    }
                }
                if (eventStatisCode.equals(DicDataEnum.VOLTAGE_DIP.getCode())) {
                    // 日均电压暂降
                    vo.setDayVoltageDip(po.getEEventMeasurementAverage());
                    // 累计电压暂降
                    vo.setCumulativeVoltageDip(po.getEventMeasurementAccrued());
                    if (lineSortCode.equals(DicDataEnum.ONE_LINE.getCode())) {
                        // 日均电压暂降占比
                        vo.setDayVoltageDipProportion(po.getEEventMeasurementRatioAverage());
                        // 累计电压暂降占比
                        vo.setCumulativeVoltageDipProportion(po.getEEventMeasurementRatioAccrued());
                        vo.setVoltageDipFreq(po.getEEventFreq());
                        vo.setVoltageDipCount(po.getEEventCount());
                    }
                }

            }
            result.add(vo);
        });
        return result;
    }

    /**
     * 获取单位id
     *
     * @param param 条件参数
     * @return 单位id
     */
    private List<PwPmsMonitorDTO> getPwMonitorList(PwUniversalFrontEndParam param) {
        // 获取单位下的监测点id集合
        PwPmsMonitorParam pwPmsMonitorParam = new PwPmsMonitorParam();
        pwPmsMonitorParam.setOrgId(param.getId());
        pwPmsMonitorParam.setMonitorSort(param.getMonitorSort());
        return monitorClient
                .getPwMonitorList(pwPmsMonitorParam)
                .getData();
    }

    /**
     * 获取配网id
     */
    private String getDistributionPoint() {
        return dicDataFeignClient
                .getDicDataByCode(DicDataEnum.DISTRIBUTION_POINT.getCode())
                .getData().getId();
    }
}
