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

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.common.pojo.dto.SimpleDTO;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.device.pms.api.MonitorClient;
import com.njcn.device.pms.api.PmsGeneralDeviceInfoClient;
import com.njcn.device.pms.pojo.dto.PmsGeneralDeviceDTO;
import com.njcn.device.pms.pojo.dto.PmsMonitorDTO;
import com.njcn.device.pms.pojo.param.PmsDeviceInfoParam;
import com.njcn.device.pms.pojo.param.PmsMonitorParam;
import com.njcn.harmonic.mapper.majornetwork.RMpBenchmarkLevelQMapper;
import com.njcn.harmonic.pojo.param.RMpBenchmarkLevelParam;
import com.njcn.harmonic.pojo.po.RMpBenchmarkLevelQ;
import com.njcn.harmonic.pojo.vo.RMpBenchmarkLevelVO;
import com.njcn.harmonic.service.majornetwork.RMpBenchmarkLevelQService;
import com.njcn.system.api.DicDataFeignClient;
import com.njcn.system.enums.DicDataTypeEnum;
import com.njcn.system.pojo.po.DictData;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

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

/**
* @author jianghf
* @description 针对表【r_mp_benchmark_level_q】的数据库操作Service实现
* @createDate 2022-10-11 10:32:18
*/
@Service
@RequiredArgsConstructor
public class RMpBenchmarkLevelQServiceImpl extends ServiceImpl<RMpBenchmarkLevelQMapper, RMpBenchmarkLevelQ>
implements RMpBenchmarkLevelQService {

    private final DicDataFeignClient dicDataFeignClient;

    private final PmsGeneralDeviceInfoClient pmsGeneralDeviceInfoClient;

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

    @Override
    public List<RMpBenchmarkLevelVO> getRMpBenchmarkLevelList(RMpBenchmarkLevelParam rMpBenchmarkLevelParam) {
        //提取查询条件
        String id = rMpBenchmarkLevelParam.getId(); //单位id
        if (StringUtils.isBlank(id)) {
            throw new BusinessException(CommonResponseEnum.NO_DATA, "单位id不可为空");
        }
        String startTime = rMpBenchmarkLevelParam.getStartTime(); //开始时间
        String endTime = rMpBenchmarkLevelParam.getEndTime(); //截止时间
        String benchmarkIndicator = rMpBenchmarkLevelParam.getBenchmarkIndicator(); //评价指标
        List <String> voltageLevelParamList = StringUtils.isNotBlank(rMpBenchmarkLevelParam.getVoltageLevel()) ? Arrays.asList(rMpBenchmarkLevelParam.getVoltageLevel().split(",")) : null; //电压等级

        //获取电压等级的字典
        List<DictData> voltageLevelList = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEV_VOLTAGE.getCode()).getData();
        //将电压信息转成map，key：id  value：name
        Map<String, String> voltageLevelMap = voltageLevelList.stream().collect(Collectors.toMap(DictData::getId, DictData::getName));
        //获取基准水平评价指标字典
        List<DictData> benchmarkIndicatorList = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.BENCHMARK_INDICATORS.getCode()).getData();
        //将基准水平评价指标信息转成map，key：id  value：name
        Map<String, String> benchmarkIndicatorMap = benchmarkIndicatorList.stream().collect(Collectors.toMap(DictData::getId, DictData::getName));

        //查询所有子单位下的所有监测点
        PmsDeviceInfoParam pmsDeviceInfoParam = new PmsDeviceInfoParam(id);
        pmsDeviceInfoParam.setStatisticalType(new SimpleDTO());
        if (CollUtil.isNotEmpty(voltageLevelParamList)) {
            //查询条件：电压等级（筛选电压等级为voltageLevel的监测点）
            List<SimpleDTO> simpleDTOList = voltageLevelParamList.stream().map(item -> {
                SimpleDTO simpleDTO = new SimpleDTO();
                simpleDTO.setId(item);
                return simpleDTO;
            }).collect(Collectors.toList());
            pmsDeviceInfoParam.setVoltageLevel(simpleDTOList);
        }
        //获取到该部门的所有子部门的监测点idList
        List<PmsGeneralDeviceDTO> pmsDeviceInfoWithInOrg = pmsGeneralDeviceInfoClient.getPmsDeviceInfoWithInOrg(pmsDeviceInfoParam).getData();
        //过滤出业务需要的监测点id集合
        List<String> firstMonitorIdList = new ArrayList<>(); //只用于合并多个部门的监测点id
        pmsDeviceInfoWithInOrg.forEach(item -> firstMonitorIdList.addAll(item.getMonitorIdList()));
        List<String> lastMonitorIdList = firstMonitorIdList.stream().distinct().collect(Collectors.toList()); //最终的监测点id集合
        //如果没有监测点id信息，直接返回空集合
        if (CollUtil.isEmpty(lastMonitorIdList)) {
            return new ArrayList<>();
        }
        //查询对应的监测点完整信息 并转为key：监测点id value：监测点实体的map集合
//        LambdaQueryWrapper<Monitor> monitorWrapper = new LambdaQueryWrapper<>();
//        monitorWrapper.in(Monitor::getId, lastMonitorIdList);
        PmsMonitorParam pmsMonitorInfoParam = new PmsMonitorParam();
        pmsMonitorInfoParam.setMonitorIds(lastMonitorIdList);
        //监测点标签集合
        pmsMonitorInfoParam.setMonitorTags(rMpBenchmarkLevelParam.getMonitorTags());
        Map<String, PmsMonitorDTO> monitorMap = monitorClient.getMonitorInfoListByCond(pmsMonitorInfoParam).getData().stream().collect(Collectors.toMap(PmsMonitorDTO::getId, monitor -> monitor));
        //查询【基准水平-月】数据
        /*组装条件：where measurement_point_id in (monitorIdList) and data_date >= startTime
                   and data_date <= endTime and voltage_level
        */
        LambdaQueryWrapper<RMpBenchmarkLevelQ> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(CollUtil.isNotEmpty(lastMonitorIdList), RMpBenchmarkLevelQ::getMeasurementPointId, lastMonitorIdList)
                .ge(StringUtils.isNotBlank(startTime), RMpBenchmarkLevelQ::getDataDate, startTime)
                .le(StringUtils.isNotBlank(endTime), RMpBenchmarkLevelQ::getDataDate, endTime);
        List<RMpBenchmarkLevelQ> list = this.list(lambdaQueryWrapper);
        List<RMpBenchmarkLevelVO> resultList = list.stream().map(item -> {
            //封装前端需要的对象
            RMpBenchmarkLevelVO rMpBenchmarkLevelVO = new RMpBenchmarkLevelVO();
            BeanUtils.copyProperties(item, rMpBenchmarkLevelVO);
            PmsGeneralDeviceDTO pmsGeneralDeviceDTO = pmsDeviceInfoWithInOrg.stream().filter(dto -> dto.getMonitorIdList().contains(item.getMeasurementPointId()))
                    .collect(Collectors.toList()).get(0);
            //单位信息
            rMpBenchmarkLevelVO.setOrgNo(pmsGeneralDeviceDTO.getIndex()); //单位id
            rMpBenchmarkLevelVO.setOrgName(pmsGeneralDeviceDTO.getName()); //单位名称
            //基准水平评价指标
            rMpBenchmarkLevelVO.setBenchmarkIndicator(benchmarkIndicator); //基准水平评价指标id
            rMpBenchmarkLevelVO.setBenchmarkIndicatorName(benchmarkIndicatorMap.get(benchmarkIndicator)); //基准水平评价指标
            //监测点信息
            rMpBenchmarkLevelVO.setMonitorTag(monitorMap.get(item.getMeasurementPointId()).getMonitorTag());
            rMpBenchmarkLevelVO.setMeasurementPointName(monitorMap.get(item.getMeasurementPointId()).getName()); //监测点名称
            //电压等级
            rMpBenchmarkLevelVO.setVoltageLevel(monitorMap.get(item.getMeasurementPointId()).getVoltageLevel());
            rMpBenchmarkLevelVO.setVoltageLevelName(voltageLevelMap.get(monitorMap.get(item.getMeasurementPointId()).getVoltageLevel()));
            return rMpBenchmarkLevelVO;
        }).collect(Collectors.toList());
        /*添加type在区分接口返回值*/
        List<RMpBenchmarkLevelVO> finalList= new ArrayList<> ();
        if(Objects.equals (rMpBenchmarkLevelParam.getReturnType (), "1")){
            Map<String, List<RMpBenchmarkLevelVO>> collect = resultList.stream ( ).collect (Collectors.groupingBy (temp -> temp.getOrgName ( ) + temp.getVoltageLevel ()));
            collect.forEach ((k, v) ->{
                RMpBenchmarkLevelVO  rMpBenchmarkLevelVO = new RMpBenchmarkLevelVO();
                rMpBenchmarkLevelVO.setOrgName (v.get (0).getOrgName ());
                rMpBenchmarkLevelVO.setVoltageLevel (v.get (0).getVoltageLevel ());
                rMpBenchmarkLevelVO.setVoltageLevelName (v.get (0).getVoltageLevelName ());
                rMpBenchmarkLevelVO.setBenchmarkIndicator(v.get (0).getBenchmarkIndicator ());
                rMpBenchmarkLevelVO.setBenchmarkIndicatorName(v.get (0).getBenchmarkIndicatorName ());
                rMpBenchmarkLevelVO.setVoltageAvg (Double.valueOf (df.format (v.stream ().
                        mapToDouble (RMpBenchmarkLevelVO::getVoltageAvg).
                        average ().
                        getAsDouble ())));
                rMpBenchmarkLevelVO.setVoltageSd (Double.valueOf (df.format (v.stream ().
                        mapToDouble (RMpBenchmarkLevelVO::getVoltageSd).
                        average ().
                        getAsDouble ())));
                rMpBenchmarkLevelVO.setUnbalanceAvg (Double.valueOf (df.format (v.stream ().
                        mapToDouble (RMpBenchmarkLevelVO::getUnbalanceAvg).
                        average ().
                        getAsDouble ())));
                rMpBenchmarkLevelVO.setUnbalanceSd (Double.valueOf (df.format (v.stream ().
                        mapToDouble (RMpBenchmarkLevelVO::getUnbalanceSd).
                        average ().
                        getAsDouble ())));
                rMpBenchmarkLevelVO.setVthdAvg (Double.valueOf (df.format (v.stream ().
                        mapToDouble (RMpBenchmarkLevelVO::getVthdAvg).
                        average ().
                        getAsDouble ())));
                rMpBenchmarkLevelVO.setVthdSd (Double.valueOf (df.format (v.stream ().
                        mapToDouble (RMpBenchmarkLevelVO::getVthdSd).
                        average ().
                        getAsDouble ())));
                rMpBenchmarkLevelVO.setFlickerAvg (Double.valueOf (df.format (v.stream ().
                        mapToDouble (RMpBenchmarkLevelVO::getFlickerAvg).
                        average ().
                        getAsDouble ())));
                rMpBenchmarkLevelVO.setFlickerSd (Double.valueOf (df.format (v.stream ().
                        mapToDouble (RMpBenchmarkLevelVO::getFlickerSd).
                        average ().
                        getAsDouble ())));

                finalList.add (rMpBenchmarkLevelVO);
            });
            return finalList;
        }
        if(CollUtil.isNotEmpty(finalList)){
            finalList.sort(Comparator.comparing(x->x.getOrgName()+";"+x.getVoltageLevelName()));
        }
        return finalList;
    }

}
