package com.njcn.prepare.harmonic.service.mysql.upload.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.jeffreyning.mybatisplus.service.MppServiceImpl;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.device.biz.commApi.CommTerminalGeneralClient;
import com.njcn.device.biz.pojo.dto.*;
import com.njcn.device.biz.pojo.param.DeptGetLineParam;
import com.njcn.device.pms.pojo.po.GeneratrixWire;
import com.njcn.device.pms.pojo.po.Monitor;
import com.njcn.device.pms.pojo.po.PmsMidLedger;
import com.njcn.harmonic.pojo.dto.LineDataDto;
import com.njcn.harmonic.pojo.po.dim.RDimVoltageD;
import com.njcn.harmonic.pojo.po.upload.PmsRunStatisticD;
import com.njcn.harmonic.pojo.po.upload.PmsRunStatisticM;
import com.njcn.harmonic.pojo.po.upload.PmsRunStatisticY;
import com.njcn.harmonic.pojo.po.upload.RUploadEvaluationDataD;
import com.njcn.prepare.harmonic.enums.UploadEnum;
import com.njcn.prepare.harmonic.mapper.mysql.dim.GeneratrixWireMapper;
import com.njcn.prepare.harmonic.mapper.mysql.dim.PmsMidLedgerMapper;
import com.njcn.prepare.harmonic.mapper.mysql.dim.RDimVoltageDMapper;
import com.njcn.prepare.harmonic.mapper.mysql.line.PmsMonitorMapper;
import com.njcn.prepare.harmonic.mapper.mysql.upload.PmsRunStatisticDMapper;
import com.njcn.prepare.harmonic.mapper.mysql.upload.RUploadEvaluationDataDMapper;
import com.njcn.prepare.harmonic.pojo.bo.CalculatedParam;
import com.njcn.prepare.harmonic.pojo.dto.BusBarDto;
import com.njcn.prepare.harmonic.service.mysql.upload.IPmsRunStatisticMService;
import com.njcn.prepare.harmonic.service.mysql.upload.IPmsRunStatisticYService;
import com.njcn.prepare.harmonic.service.mysql.upload.IRUploadEvaluationDataDService;
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.po.Dept;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 电能质量基准水平评估数据-日表 服务实现类
 * </p>
 *
 * @author xuyang
 * @since 2023-12-12
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class RUploadEvaluationDataDServiceImpl extends MppServiceImpl<RUploadEvaluationDataDMapper, RUploadEvaluationDataD> implements IRUploadEvaluationDataDService {

    private final RDimVoltageDMapper rDimVoltageDMapper;
    private final DeptFeignClient deptFeignClient;
    private final PmsMonitorMapper pmsMonitorMapper;
    private final PmsMidLedgerMapper pmsMidLedgerMapper;
    private final DicDataFeignClient dicDataFeignClient;
    private final CommTerminalGeneralClient commTerminalGeneralClient;
    private final GeneratrixWireMapper generatrixWireMapper;
    private final PmsRunStatisticDMapper runStatisticDMapper;
    private final IPmsRunStatisticMService runStatisticMService;
    private final IPmsRunStatisticYService runStatisticYService;

    @Override
    public void insertEvaluationDataDay(CalculatedParam<DeptGetChildrenMoreDTO> calculatedParam) {
        List<RUploadEvaluationDataD> result = new ArrayList<>();
        final Double defaultValue = 3.1415926;
        //首先获取pms_run_statistic表是否存在执行日期的数据
        List<PmsRunStatisticD> pmsRunStatisticsListD = runStatisticDMapper.selectList(new LambdaQueryWrapper<PmsRunStatisticD>().eq(PmsRunStatisticD::getStatisticDate, calculatedParam.getDataDate()));

        //获取中台母线信息
        List<PmsMidLedger> allMidBusBarList = this.getBusBarInfo();

        //获取在运测点
        List<Monitor> monitorList = this.getRunMonitorList(pmsRunStatisticsListD);


        //获取监测母线
        List<GeneratrixWire> superviseBusList;
        if (CollUtil.isNotEmpty(pmsRunStatisticsListD)) {
            List<String> wireIds = pmsRunStatisticsListD.stream().filter(x -> StrUtil.isNotBlank(x.getOnlineBusIds())).flatMap(x -> CollectionUtil.toList(x.getOnlineBusIds().split(StrUtil.COMMA)).stream()).distinct().collect(Collectors.toList());
            if(CollUtil.isNotEmpty(wireIds)){
                LambdaQueryWrapper<GeneratrixWire> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                lambdaQueryWrapper.eq(GeneratrixWire::getStatus, DataStateEnum.ENABLE.getCode())
                        .in(GeneratrixWire::getId, wireIds);
                superviseBusList = generatrixWireMapper.selectList(lambdaQueryWrapper);
            }else{
                List<Monitor> list1 = this.getPmsMonitor();
                superviseBusList = this.getCnBusBarInfo(list1);
            }
        } else {
            //获取监测点信息
            List<Monitor> list1 = this.getPmsMonitor();
            superviseBusList = this.getCnBusBarInfo(list1);
        }
        //获取单位下各电压等级数据

        Dept rootDept = deptFeignClient.getRootDept().getData();
        DeptGetLineParam deptGetLineParam = new DeptGetLineParam();
        deptGetLineParam.setDeptId(rootDept.getId());
        List<DeptGetBusBarDTO> barDto = commTerminalGeneralClient.deptBusBar(deptGetLineParam).getData();

        List<BusBarDto> busBarList = this.getBusBarNum(superviseBusList, allMidBusBarList, barDto);
        List<BusBarDto> allDept = this.getAllDeptLineNum(busBarList, deptGetLineParam);
        //获取省级单位id
        String provinceId = deptFeignClient.getDepSonIdByDeptId(rootDept.getId()).getData().get(0);
        Dept dept = deptFeignClient.getDeptById(provinceId).getData();
        //获取所有单位
        List<Dept> deptList = deptFeignClient.getAllDept().getData();
        Map<String, List<Dept>> deptMap = deptList.stream().collect(Collectors.groupingBy(Dept::getCode));

        List<DeptGetChildrenMoreDTO> list = calculatedParam.getIdList();
        list.forEach(item -> {
            if (Objects.equals(Integer.parseInt(UploadEnum.NJCN_DEPT_LEVEL_1.getCode()), item.getDeptLevel())
                    //县数据
                    || Objects.equals(Integer.parseInt(UploadEnum.NJCN_DEPT_LEVEL_4.getCode()),item.getDeptLevel())
            ) {
                return;
            }

            BusBarDto busBarDto = allDept.stream().filter(o -> Objects.equals(o.getOrgId(), item.getUnitId())).findFirst().orElse(null);

            List<Monitor> deptMonitorList = monitorList.stream().filter(t->item.getUnitId().contains(t.getOrgId())).collect(Collectors.toList());

            if(Objects.isNull(busBarDto) || busBarDto.getAllOnlineBusNum()==0){
                return;
            }

            RUploadEvaluationDataD rUploadEvaluationDataD = new RUploadEvaluationDataD();
            rUploadEvaluationDataD.setProvinceId(dept.getCode());
            rUploadEvaluationDataD.setProvinceName(dept.getName());
            rUploadEvaluationDataD.setDataSources(UploadEnum.DATA_SOURCES_01.getCode());
            rUploadEvaluationDataD.setStatisticalDate(calculatedParam.getDataDate());
            rUploadEvaluationDataD.setComputeDate(calculatedParam.getDataDate());
            rUploadEvaluationDataD.setStatisticalType(UploadEnum.STATISTICAL_TYPE_03.getCode());
            rUploadEvaluationDataD.setUploadStatus(Integer.parseInt(UploadEnum.UPLOAD_STATUS_0.getCode()));
            this.judgeLevel(item.getDeptLevel(), rUploadEvaluationDataD, item.getUnitId(), item.getUnitName(), deptList, deptMap);


            /*** 计算无电压等级的数据*/
            RUploadEvaluationDataD dto = this.getLineNum(busBarDto, "0");
            //电压
            RUploadEvaluationDataD dto1 = this.channelData(rUploadEvaluationDataD, defaultValue, defaultValue, UploadEnum.INDEX_TYPE_01.getCode(), 0, "0", dto);
            result.add(dto1);
            //长时间闪变
            RUploadEvaluationDataD dto2 = this.channelData(rUploadEvaluationDataD, defaultValue, defaultValue, UploadEnum.INDEX_TYPE_02.getCode(), 0, "0", dto);
            result.add(dto2);
            //三相电压不平衡
            RUploadEvaluationDataD dto3 = this.channelData(rUploadEvaluationDataD, defaultValue, defaultValue, UploadEnum.INDEX_TYPE_03.getCode(), 0, "0", dto);
            result.add(dto3);
            //电压总谐波畸变率
            RUploadEvaluationDataD dto4 = this.channelData(rUploadEvaluationDataD, defaultValue, defaultValue, UploadEnum.INDEX_TYPE_04.getCode(), 0, "0", dto);
            result.add(dto4);
            //各次谐波电压
            this.channelHarmonicData(rUploadEvaluationDataD, result, null,null, UploadEnum.INDEX_TYPE_05.getCode(), "0", dto, null);
            //负序电流
            RUploadEvaluationDataD dto6 = this.channelData(rUploadEvaluationDataD, defaultValue, defaultValue, UploadEnum.INDEX_TYPE_06.getCode(), 0, "0", dto);
            result.add(dto6);
            /*** 计算分电压等级的数据*/
            if (CollUtil.isNotEmpty(busBarDto.getVoltageChild())) {
                busBarDto.getVoltageChild().forEach(item2 -> {
                    RDimVoltageD rDimVoltageD = this.getDimVoltageData(item.getUnitId(), calculatedParam.getDataDate(), item2.getVoltageLevel(),"avg");
                    RDimVoltageD rDimVoltageDSd = this.getDimVoltageData(item.getUnitId(), calculatedParam.getDataDate(), item2.getVoltageLevel(),"sd");

                    List<Monitor> voltageMonitor = deptMonitorList.stream().filter(it->it.getVoltageLevel().equals(item2.getVoltageLevel())).collect(Collectors.toList());

                    RUploadEvaluationDataD dto0 = this.getLineNum(busBarDto, item2.getVoltageLevel());
                    //电压
                    RUploadEvaluationDataD dto11 = this.channelData(rUploadEvaluationDataD, Objects.isNull(rDimVoltageD) ? defaultValue : rDimVoltageD.getV(), Objects.isNull(rDimVoltageDSd) ? defaultValue : rDimVoltageDSd.getV(), UploadEnum.INDEX_TYPE_01.getCode(), 0, item2.getVoltageLevel(), dto0);
                    result.add(dto11);
                    //长时间闪变
                    RUploadEvaluationDataD dto22 = this.channelData(rUploadEvaluationDataD, Objects.isNull(rDimVoltageD) ? defaultValue : rDimVoltageD.getPst(), Objects.isNull(rDimVoltageDSd) ? defaultValue : rDimVoltageDSd.getPst(), UploadEnum.INDEX_TYPE_02.getCode(), 0, item2.getVoltageLevel(), dto0);
                    result.add(dto22);
                    //三相电压不平衡
                    RUploadEvaluationDataD dto33 = this.channelData(rUploadEvaluationDataD, Objects.isNull(rDimVoltageD) ? defaultValue : rDimVoltageD.getVUnbalance(), Objects.isNull(rDimVoltageDSd) ? defaultValue : rDimVoltageDSd.getVUnbalance(), UploadEnum.INDEX_TYPE_03.getCode(), 0, item2.getVoltageLevel(), dto0);
                    result.add(dto33);
                    //电压总谐波畸变率
                    RUploadEvaluationDataD dto44 = this.channelData(rUploadEvaluationDataD, Objects.isNull(rDimVoltageD) ? defaultValue : rDimVoltageD.getVThd(), Objects.isNull(rDimVoltageDSd) ? defaultValue : rDimVoltageDSd.getVThd(), UploadEnum.INDEX_TYPE_04.getCode(), 0, item2.getVoltageLevel(), dto0);
                    result.add(dto44);
                    //各次谐波电压
                    List<Double> valueList = new ArrayList<>();
                    List<Double> valueListSd = new ArrayList<>();
                    if (!Objects.isNull(rDimVoltageD)) {
                        valueList = Arrays.asList(rDimVoltageD.getV2(), rDimVoltageD.getV3(), rDimVoltageD.getV4(), rDimVoltageD.getV5(), rDimVoltageD.getV6(), rDimVoltageD.getV7(), rDimVoltageD.getV8(), rDimVoltageD.getV9(), rDimVoltageD.getV10()
                                , rDimVoltageD.getV11(), rDimVoltageD.getV12(), rDimVoltageD.getV13(), rDimVoltageD.getV14(), rDimVoltageD.getV15(), rDimVoltageD.getV16(), rDimVoltageD.getV17(), rDimVoltageD.getV18(), rDimVoltageD.getV19(), rDimVoltageD.getV20()
                                , rDimVoltageD.getV21(), rDimVoltageD.getV22(), rDimVoltageD.getV23(), rDimVoltageD.getV24(), rDimVoltageD.getV25(), rDimVoltageD.getV26(), rDimVoltageD.getV27(), rDimVoltageD.getV28(), rDimVoltageD.getV29(), rDimVoltageD.getV30()
                                , rDimVoltageD.getV31(), rDimVoltageD.getV32(), rDimVoltageD.getV33(), rDimVoltageD.getV34(), rDimVoltageD.getV35(), rDimVoltageD.getV36(), rDimVoltageD.getV37(), rDimVoltageD.getV38(), rDimVoltageD.getV39(), rDimVoltageD.getV40()
                                , rDimVoltageD.getV41(), rDimVoltageD.getV42(), rDimVoltageD.getV43(), rDimVoltageD.getV44(), rDimVoltageD.getV45(), rDimVoltageD.getV46(), rDimVoltageD.getV47(), rDimVoltageD.getV48(), rDimVoltageD.getV49(), rDimVoltageD.getV50());
                    }
                    if (!Objects.isNull(rDimVoltageDSd)) {
                        valueListSd = Arrays.asList(rDimVoltageDSd.getV2(), rDimVoltageDSd.getV3(), rDimVoltageDSd.getV4(), rDimVoltageDSd.getV5(), rDimVoltageDSd.getV6(), rDimVoltageDSd.getV7(), rDimVoltageDSd.getV8(), rDimVoltageDSd.getV9(), rDimVoltageDSd.getV10()
                                , rDimVoltageDSd.getV11(), rDimVoltageDSd.getV12(), rDimVoltageDSd.getV13(), rDimVoltageDSd.getV14(), rDimVoltageDSd.getV15(), rDimVoltageDSd.getV16(), rDimVoltageDSd.getV17(), rDimVoltageDSd.getV18(), rDimVoltageDSd.getV19(), rDimVoltageDSd.getV20()
                                , rDimVoltageDSd.getV21(), rDimVoltageDSd.getV22(), rDimVoltageDSd.getV23(), rDimVoltageDSd.getV24(), rDimVoltageDSd.getV25(), rDimVoltageDSd.getV26(), rDimVoltageDSd.getV27(), rDimVoltageDSd.getV28(), rDimVoltageDSd.getV29(), rDimVoltageDSd.getV30()
                                , rDimVoltageDSd.getV31(), rDimVoltageDSd.getV32(), rDimVoltageDSd.getV33(), rDimVoltageDSd.getV34(), rDimVoltageDSd.getV35(), rDimVoltageDSd.getV36(), rDimVoltageDSd.getV37(), rDimVoltageDSd.getV38(), rDimVoltageDSd.getV39(), rDimVoltageDSd.getV40()
                                , rDimVoltageDSd.getV41(), rDimVoltageDSd.getV42(), rDimVoltageDSd.getV43(), rDimVoltageDSd.getV44(), rDimVoltageDSd.getV45(), rDimVoltageDSd.getV46(), rDimVoltageDSd.getV47(), rDimVoltageDSd.getV48(), rDimVoltageDSd.getV49(), rDimVoltageDSd.getV50());
                    }
                    this.channelHarmonicData(rUploadEvaluationDataD, result, valueList,valueListSd, UploadEnum.INDEX_TYPE_05.getCode(), item2.getVoltageLevel(), dto0, voltageMonitor);
                    //负序电流
                    RUploadEvaluationDataD dto66 = this.channelData(rUploadEvaluationDataD, Objects.isNull(rDimVoltageD) ? defaultValue : rDimVoltageD.getINeg(), Objects.isNull(rDimVoltageDSd) ? defaultValue : rDimVoltageDSd.getINeg(), UploadEnum.INDEX_TYPE_06.getCode(), 0, item2.getVoltageLevel(), dto0);
                    result.add(dto66);
                });
            }
        });
        if (CollUtil.isNotEmpty(result)) {
            this.saveOrUpdateBatchByMultiId(result, 1000);
        }
    }



    private List<Monitor> getRunMonitorList(List<PmsRunStatisticD> pmsRunStatisticsListD) {
        List<String> monitorIds = pmsRunStatisticsListD.stream().filter(x -> StrUtil.isNotBlank(x.getRunMonitorIds())).flatMap(x -> CollectionUtil.toList(x.getRunMonitorIds().split(StrUtil.COMMA)).stream()).distinct().collect(Collectors.toList());
        if (CollUtil.isNotEmpty(monitorIds)) {
            LambdaQueryWrapper<Monitor> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.select(Monitor::getId, Monitor::getVoltageLevel, Monitor::getName,Monitor::getOrgId).eq(Monitor::getStatus, DataStateEnum.ENABLE.getCode())
                    .in(Monitor::getId, monitorIds);
            return pmsMonitorMapper.selectList(lambdaQueryWrapper);
        }else {
            return new ArrayList<>();
        }
    }



    /**
     * 通过日表取平均值，作为月表数据
     *
     * @param calculatedParam
     */
    @Override
    public void insertEvaluationDataMonth(CalculatedParam<DeptGetChildrenMoreDTO> calculatedParam) {
        //开始月份
        String beginMonth = DateUtil.format(DateUtil.beginOfMonth(DateUtil.parse(calculatedParam.getDataDate(), DatePattern.NORM_MONTH_PATTERN)), DatePattern.NORM_MONTH_PATTERN);
        //起始时间
        String startTime = DateUtil.format(DateUtil.beginOfMonth(DateUtil.parse(calculatedParam.getDataDate(), DatePattern.NORM_DATE_PATTERN)), DatePattern.NORM_DATE_PATTERN);
        //结束时间
        String endTime = DateUtil.format(DateUtil.endOfMonth(DateUtil.parse(calculatedParam.getDataDate(), DatePattern.NORM_DATE_PATTERN)), DatePattern.NORM_DATE_PATTERN);
        //数据集
        List<RUploadEvaluationDataD> list = this.baseMapper.evaluationMonthData(beginMonth, startTime, endTime, "02");

        List<PmsRunStatisticM> pmsRunStatisticsList = runStatisticMService.selectListByDate(startTime, endTime,calculatedParam.getDataDate());
        //获取中台母线信息
        List<PmsMidLedger> list2 = this.getBusBarInfo();
        //获取灿能母线信息
        List<GeneratrixWire> list3;

        if (CollUtil.isNotEmpty(pmsRunStatisticsList)) {
            List<String> wireIds = pmsRunStatisticsList.stream()
                    .filter(x -> StrUtil.isNotBlank(x.getOnlineBusIds()))
                    .flatMap(x -> CollectionUtil.toList(x.getOnlineBusIds().split(StrUtil.COMMA)).stream()).distinct().collect(Collectors.toList());
            if(CollUtil.isNotEmpty(wireIds)){
                LambdaQueryWrapper<GeneratrixWire> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                lambdaQueryWrapper.eq(GeneratrixWire::getStatus, DataStateEnum.ENABLE.getCode())
                        .in(GeneratrixWire::getId, wireIds);
                list3 = generatrixWireMapper.selectList(lambdaQueryWrapper);
            }else{
                List<Monitor> list1 = this.getPmsMonitor();
                list3 = this.getCnBusBarInfo(list1);
            }
        } else {
            //获取监测点信息
            List<Monitor> list1 = this.getPmsMonitor();
            list3 = this.getCnBusBarInfo(list1);
        }


        //获取单位下各电压等级数据
        DeptGetLineParam deptGetLineParam = new DeptGetLineParam();
        Dept data = deptFeignClient.getRootDept().getData();
        deptGetLineParam.setDeptId(data.getId());
        List<DeptGetBusBarDTO> barDto = commTerminalGeneralClient.deptBusBar(deptGetLineParam).getData();


        List<BusBarDto> busBarList = new ArrayList<>();
        for (DeptGetBusBarDTO deptGetBusBarDTO : barDto) {
            BusBarDto busBarDto = new BusBarDto();
            busBarDto.setOrgId(deptGetBusBarDTO.getUnitId());
            Integer online = (int) list3.stream().map(GeneratrixWire::getId).filter(id -> deptGetBusBarDTO.getBusBarIds().contains(id)).distinct().count();
            busBarDto.setAllMonitorBusNum(online);
            Integer all = (int) list2.stream().filter(item -> deptGetBusBarDTO.getUnitChildrenList().contains(item.getSectionId())).count();
            busBarDto.setAllOnlineBusNum(all);

            if (all > 0) {
                busBarDto.setAllMonitorRate(BigDecimal.valueOf((double) online / all).setScale(4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).doubleValue());
            }
            busBarList.add(busBarDto);
        }
        Map<String, BusBarDto> mapBus = busBarList.stream().collect(Collectors.toMap(BusBarDto::getOrgId, Function.identity()));


        if (CollUtil.isNotEmpty(list)) {

            list.forEach(item -> {

                item.setId(IdUtil.simpleUUID());
                item.setComputeDate(calculatedParam.getDataDate());

                String statisticalLevel = item.getStatisticalLevel();
                String id = null;
                if ("5".equals(statisticalLevel)) {
                    id = item.getCountyId();
                } else if ("4".equals(statisticalLevel)) {
                    id = item.getCityId();
                } else if ("3".equals(statisticalLevel)) {
                    id = item.getProvinceId();
                } else {

                }

                if (mapBus.containsKey(id)) {
                    BusBarDto busStats = mapBus.get(id);
                    item.setMonitorBusNum(busStats.getAllMonitorBusNum());
                    item.setOnlineBusNum(busStats.getAllOnlineBusNum());
                    item.setMonitorBusRate(busStats.getAllMonitorRate());
                } else {
                    item.setMonitorBusNum(0);
                    item.setOnlineBusNum(0);
                    item.setMonitorBusRate(0.0);
                }

            });
            this.saveOrUpdateBatchByMultiId(list, 1000);
        }
    }

    /**
     * 通过日表取平均值，作为年表数据
     *
     * @param calculatedParam
     */
    @Override
    public void insertEvaluationDataYear(CalculatedParam<DeptGetChildrenMoreDTO> calculatedParam) {
        //开始年
        String begin = DateUtil.format(DateUtil.beginOfYear(DateUtil.parse(calculatedParam.getDataDate(), DatePattern.NORM_YEAR_PATTERN)), DatePattern.NORM_YEAR_PATTERN);
        //起始时间
        String startTime = DateUtil.format(DateUtil.beginOfYear(DateUtil.parse(calculatedParam.getDataDate(), DatePattern.NORM_DATE_PATTERN)), DatePattern.NORM_DATE_PATTERN);
        //结束时间
        String endTime = DateUtil.format(DateUtil.endOfYear(DateUtil.parse(calculatedParam.getDataDate(), DatePattern.NORM_DATE_PATTERN)), DatePattern.NORM_DATE_PATTERN);
        //数据集
        List<RUploadEvaluationDataD> list = this.baseMapper.evaluationMonthData(begin, startTime, endTime, "01");

        List<PmsRunStatisticY> pmsRunStatisticsList = runStatisticYService.selectListByDate(startTime, endTime,calculatedParam.getDataDate());

        //获取中台母线信息
        List<PmsMidLedger> list2 = this.getBusBarInfo();
        //获取灿能母线信息
        List<GeneratrixWire> list3;
        if (CollUtil.isNotEmpty(pmsRunStatisticsList)) {
            List<String> wireIds = pmsRunStatisticsList.stream()
                    .filter(x -> StrUtil.isNotBlank(x.getOnlineBusIds()))
                    .flatMap(x -> CollectionUtil.toList(x.getOnlineBusIds().split(StrUtil.COMMA)).stream()).distinct().collect(Collectors.toList());
            if(CollUtil.isNotEmpty(wireIds)){
                LambdaQueryWrapper<GeneratrixWire> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                lambdaQueryWrapper.eq(GeneratrixWire::getStatus, DataStateEnum.ENABLE.getCode())
                        .in(GeneratrixWire::getId, wireIds);
                list3 = generatrixWireMapper.selectList(lambdaQueryWrapper);
            }else{
                List<Monitor> list1 = this.getPmsMonitor();
                list3 = this.getCnBusBarInfo(list1);
            }
        } else {
            //获取监测点信息
            List<Monitor> list1 = this.getPmsMonitor();
            list3 = this.getCnBusBarInfo(list1);
        }

        //获取单位下各电压等级数据
        DeptGetLineParam deptGetLineParam = new DeptGetLineParam();
        Dept data = deptFeignClient.getRootDept().getData();
        deptGetLineParam.setDeptId(data.getId());
        List<DeptGetBusBarDTO> barDto = commTerminalGeneralClient.deptBusBar(deptGetLineParam).getData();


        List<BusBarDto> busBarList = new ArrayList<>();
        for (DeptGetBusBarDTO deptGetBusBarDTO : barDto) {
            BusBarDto busBarDto = new BusBarDto();
            busBarDto.setOrgId(deptGetBusBarDTO.getUnitId());
            Integer online = (int) list3.stream().map(GeneratrixWire::getId).filter(id -> deptGetBusBarDTO.getBusBarIds().contains(id)).distinct().count();
            busBarDto.setAllMonitorBusNum(online);
            Integer all = (int) list2.stream().filter(item -> deptGetBusBarDTO.getUnitChildrenList().contains(item.getSectionId())).count();
            busBarDto.setAllOnlineBusNum(all);

            if (all > 0) {
                busBarDto.setAllMonitorRate(BigDecimal.valueOf((double) online / all).setScale(4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).doubleValue());
            }
            busBarList.add(busBarDto);
        }
        Map<String, BusBarDto> mapBus = busBarList.stream().collect(Collectors.toMap(BusBarDto::getOrgId, Function.identity()));

        if (CollUtil.isNotEmpty(list)) {
            list.forEach(item -> {
                item.setId(IdUtil.simpleUUID());
                item.setComputeDate(calculatedParam.getDataDate());

                String statisticalLevel = item.getStatisticalLevel();
                String id = null;
                if ("5".equals(statisticalLevel)) {
                    id = item.getCountyId();
                } else if ("4".equals(statisticalLevel)) {
                    id = item.getCityId();
                } else if ("3".equals(statisticalLevel)) {
                    id = item.getProvinceId();
                } else {

                }

                if (mapBus.containsKey(id)) {
                    BusBarDto busStats = mapBus.get(id);
                    item.setMonitorBusNum(busStats.getAllMonitorBusNum());
                    item.setOnlineBusNum(busStats.getAllOnlineBusNum());
                    item.setMonitorBusRate(busStats.getAllMonitorRate());
                } else {
                    item.setMonitorBusNum(0);
                    item.setOnlineBusNum(0);
                    item.setMonitorBusRate(0.0);
                }

            });
            this.saveOrUpdateBatchByMultiId(list, 1000);
        }
    }

    /**
     * 获取 在运 && 正常 && 国网上送 的监测点信息
     */
    public List<Monitor> getPmsMonitor() {
        List<DictData> dicDataList = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.LINE_STATE.getCode()).getData();
        DictData dictData = dicDataList.stream().filter(o -> Objects.equals(o.getCode(), DicDataEnum.RUN.getCode())).findFirst().orElse(null);
        LambdaQueryWrapper<Monitor> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Monitor::getStatus, DataStateEnum.ENABLE.getCode())
                .eq(Monitor::getIsUpToGrid, DataStateEnum.ENABLE.getCode())
                .eq(Monitor::getMonitorState, dictData.getId());
        return pmsMonitorMapper.selectList(lambdaQueryWrapper);
    }

    /**
     * 获取中台母线信息
     * 筛选系统已有的电压等级母线
     */
    public List<PmsMidLedger> getBusBarInfo() {
        DictData RunStatus = dicDataFeignClient.getDicDataByCodeAndType(DicDataEnum.RUN.getCode(),DicDataTypeEnum.LINE_STATE.getCode()).getData();
     /*   List<DictData> dicDataList = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEV_VOLTAGE.getCode()).getData();
        List<String> list = dicDataList.stream().map(DictData::getId).collect(Collectors.toList());*/
        LambdaQueryWrapper<PmsMidLedger> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(PmsMidLedger::getLevel, DataStateEnum.ENABLE.getCode())
                .eq(PmsMidLedger::getRunStatus,RunStatus.getId())
                .eq(PmsMidLedger::getState, DataStateEnum.ENABLE.getCode());
        return pmsMidLedgerMapper.selectList(lambdaQueryWrapper);
    }

    /**
     * 获取灿能母线信息
     */
    public List<GeneratrixWire> getCnBusBarInfo(List<Monitor> list) {
        List<String> lineList = list.stream().map(Monitor::getLineId).collect(Collectors.toList());
        LambdaQueryWrapper<GeneratrixWire> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(GeneratrixWire::getStatus, DataStateEnum.ENABLE.getCode())
                .in(GeneratrixWire::getId, lineList);
        return generatrixWireMapper.selectList(lambdaQueryWrapper);
    }

    /**
     * 获取已知单位母线数量
     */
    public List<BusBarDto> getBusBarNum(List<GeneratrixWire> list1, List<PmsMidLedger> list2, List<DeptGetBusBarDTO> dto) {
        List<BusBarDto> result = new ArrayList<>();
        //中台母线
        Map<String, List<PmsMidLedger>> midMap = list2.stream().collect(Collectors.groupingBy(PmsMidLedger::getSectionId));
        for (DeptGetBusBarDTO item : dto) {
            int count = 0;
            List<BusBarDto.VoltageChild> childList = new ArrayList<>();
            BusBarDto dto1 = new BusBarDto();
            dto1.setOrgId(item.getUnitId());
            //处理中台母线
            List<PmsMidLedger> l1 = midMap.get(item.getUnitId());
            if (CollUtil.isNotEmpty(l1)) {
                dto1.setAllOnlineBusNum(l1.size());
                Map<String, List<PmsMidLedger>> voltageMap = l1.stream().collect(Collectors.groupingBy(PmsMidLedger::getVoltageLevel));
                for (String key : voltageMap.keySet()) {
                    BusBarDto.VoltageChild voltageChild = new BusBarDto.VoltageChild();
                    List<String> l2 = voltageMap.get(key).stream().map(PmsMidLedger::getId).collect(Collectors.toList());
                    voltageChild.setVoltageLevel(key);
                    voltageChild.setOnlineBusNum(l2.size());
                    //匹配wire母线表数量
                    if (CollUtil.isNotEmpty(item.getBusBarIds())) {
                        List<GeneratrixWire> l3 = list1.stream().filter(o -> item.getBusBarIds().contains(o.getId())).collect(Collectors.toList());
                        if (CollUtil.isNotEmpty(l3)) {
                            voltageChild.setMonitorBusNum(l3.size());
                        }
                    } else {
                        voltageChild.setMonitorBusNum(0);
                    }
                    voltageChild.setMonitorRate(voltageChild.getMonitorBusNum() * 100.0 / voltageChild.getOnlineBusNum());
                    childList.add(voltageChild);
//                    count = count + voltageChild.getMonitorBusNum();
                    count = voltageChild.getMonitorBusNum();
                }
                dto1.setAllMonitorBusNum(count);
                dto1.setVoltageChild(childList);
                dto1.setAllMonitorRate(dto1.getAllMonitorRate() * 100 / l1.size());
            }
            result.add(dto1);
        }
        return result;
    }

    /**
     * 组装所有单位下各个电压等级的母线数量
     */
    public List<BusBarDto> getAllDeptLineNum(List<BusBarDto> list, DeptGetLineParam deptGetLineParam) {
        List<BusBarDto> result = new ArrayList<>();
        //获取所有部门信息
        List<DeptGetBase> deptList = commTerminalGeneralClient.getDeptChildrenByParent(deptGetLineParam).getData();
        deptList.forEach(item -> {
            int count1 = 0, count2 = 0;
            List<BusBarDto.VoltageChild> children = new ArrayList<>();
            List<BusBarDto.VoltageChild> child = new ArrayList<>();
            BusBarDto busBarDto = new BusBarDto();
            busBarDto.setOrgId(item.getUnitId());
            //获取当前部门下 包含母线数量的部门
            List<BusBarDto> newList = list.stream().filter(o -> item.getUnitChildrenList().contains(o.getOrgId())).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(newList)) {
                for (BusBarDto it : newList) {
                    count1 = count1 + it.getAllMonitorBusNum();
                    count2 = count2 + it.getAllOnlineBusNum();
                    if (CollUtil.isNotEmpty(it.getVoltageChild())) {
                        child.addAll(it.getVoltageChild());
                    }
                }
                busBarDto.setAllMonitorBusNum(count1);
                busBarDto.setAllOnlineBusNum(count2);
                busBarDto.setAllMonitorRate(count2 == 0 ? 0.0 : count1 * 100 / count2);
                if (CollUtil.isNotEmpty(child)) {
                    Map<String, List<BusBarDto.VoltageChild>> map = child.stream().collect(Collectors.groupingBy(BusBarDto.VoltageChild::getVoltageLevel));
                    map.forEach((k, v) -> {
                        BusBarDto.VoltageChild c1 = new BusBarDto.VoltageChild();
                        c1.setVoltageLevel(k);
                        int monitorBusNum = (int) v.stream().mapToDouble(BusBarDto.VoltageChild::getMonitorBusNum).average().getAsDouble();
                        c1.setMonitorBusNum(monitorBusNum);
                        int online = (int) v.stream().mapToDouble(BusBarDto.VoltageChild::getOnlineBusNum).average().getAsDouble();
                        c1.setOnlineBusNum(online);
                        c1.setMonitorRate(online == 0.0 ? 0 : monitorBusNum * 100.0 / online);
                        children.add(c1);
                    });
                    busBarDto.setVoltageChild(children);
                }
            }
            result.add(busBarDto);
        });
        return result;
    }

    /**
     * 生成母线数量
     */
    public RUploadEvaluationDataD getLineNum(BusBarDto dto2, String voltage) {
        RUploadEvaluationDataD dto = new RUploadEvaluationDataD();
        if (!Objects.isNull(dto2)) {
            List<BusBarDto.VoltageChild> list = dto2.getVoltageChild();
            if (CollUtil.isNotEmpty(list)) {
                list.forEach(item -> {
//                    if (Objects.equals(item.getVoltageLevel(),voltage)){
//                        dto.setMonitorBusNum(item.getMonitorBusNum());
//                        dto.setOnlineBusNum(item.getOnlineBusNum());
//                        dto.setMonitorBusRate(item.getMonitorRate());
//                    } else if (Objects.equals(voltage, "0")){
//                        dto.setMonitorBusNum(dto2.getAllMonitorBusNum());
//                        dto.setOnlineBusNum(dto2.getAllOnlineBusNum());
//                        dto.setMonitorBusRate(dto2.getAllMonitorBusNum()*100.0d/dto2.getAllOnlineBusNum());
//                    }
                    //fixme 基准水平数据上传失败，先将各个电压等级数据调整为不区分电压等级的数据
                    dto.setMonitorBusNum(dto2.getAllMonitorBusNum());
                    dto.setOnlineBusNum(dto2.getAllOnlineBusNum());
                    dto.setMonitorBusRate(dto2.getAllMonitorBusNum() * 100.0d / dto2.getAllOnlineBusNum());
                });
            }
        }
        return dto;
    }


    /**
     * 判断单位层级
     */
    public void judgeLevel(Integer level, RUploadEvaluationDataD rUploadEvaluationDataD, String id, String name, List<Dept> deptList, Map<String, List<Dept>> map) {
        String result = "";
        if (Objects.equals(level, Integer.parseInt(UploadEnum.NJCN_DEPT_LEVEL_2.getCode()))) {
            result = UploadEnum.STATISTICAL_LEVEL_3.getCode();
            rUploadEvaluationDataD.setCityId("");
            rUploadEvaluationDataD.setCountyId("");
        } else if (Objects.equals(level, Integer.parseInt(UploadEnum.NJCN_DEPT_LEVEL_3.getCode()))) {
            result = UploadEnum.STATISTICAL_LEVEL_4.getCode();
            rUploadEvaluationDataD.setCityId(id);
            rUploadEvaluationDataD.setCityName(name);
            rUploadEvaluationDataD.setCountyId("");
        } else if (Objects.equals(level, Integer.parseInt(UploadEnum.NJCN_DEPT_LEVEL_4.getCode()))) {
            result = UploadEnum.STATISTICAL_LEVEL_5.getCode();
            List<String> list = Arrays.stream(map.get(id).get(0).getPids().split(",")).map(String::trim).collect(Collectors.toList());
            String parentCode = deptList.stream().filter(o -> Objects.equals(o.getId(), list.get(3))).findFirst().orElse(null).getCode();
            rUploadEvaluationDataD.setCityId(parentCode);
            rUploadEvaluationDataD.setCityName(map.get(parentCode).get(0).getName());
            rUploadEvaluationDataD.setCountyId(id);
            rUploadEvaluationDataD.setCountyName(name);
        }
        rUploadEvaluationDataD.setStatisticalLevel(result);
    }

    /**
     * 单个指标数据处理
     */
    public RUploadEvaluationDataD channelData(RUploadEvaluationDataD rUploadEvaluationDataD, Double value, Double sd, String indexType, Integer harmonicNum, String voltage, RUploadEvaluationDataD rUploadEvaluationDataD2) {
        RUploadEvaluationDataD dto = new RUploadEvaluationDataD();
        BeanUtils.copyProperties(rUploadEvaluationDataD, dto);
        dto.setId(IdUtil.simpleUUID());
        dto.setAvgValue(value);
        dto.setIndexType(indexType);
        dto.setHarmonicNum(harmonicNum);
        dto.setStandardDeviation(sd);
        dto.setVoltageLevel(voltage);
        dto.setMonitorBusNum(rUploadEvaluationDataD2.getMonitorBusNum());
        dto.setOnlineBusNum(rUploadEvaluationDataD2.getOnlineBusNum());
        dto.setMonitorBusRate(rUploadEvaluationDataD2.getMonitorBusRate());
        return dto;
    }

    /**
     * 各次谐波电压数据处理
     */
    public void channelHarmonicData(RUploadEvaluationDataD rUploadEvaluationDataD, List<RUploadEvaluationDataD> result, List<Double> valueList, List<Double> valueListSd, String indexType, String voltage, RUploadEvaluationDataD rUploadEvaluationDataD2, List<Monitor> line) {
        final Double defaultValue = 3.1415926;
        int length;
        if (!Objects.isNull(valueList)) {
            length = valueList.size();
        } else {
            length = 49;
        }
        for (int i = 0; i < length; i++) {
            RUploadEvaluationDataD dto = new RUploadEvaluationDataD();
            BeanUtils.copyProperties(rUploadEvaluationDataD, dto);
            dto.setId(IdUtil.simpleUUID());
            dto.setAvgValue(CollUtil.isNotEmpty(valueList) ? valueList.get(i) : defaultValue);
            dto.setIndexType(indexType);
            dto.setHarmonicNum(i + 2);
            if (Objects.equals(voltage, "0")) {
                dto.setStandardDeviation(defaultValue);
            } else {
                dto.setStandardDeviation(CollUtil.isNotEmpty(valueListSd) ? valueListSd.get(i) : defaultValue);
            }
            dto.setVoltageLevel(voltage);
            dto.setMonitorBusNum(rUploadEvaluationDataD2.getMonitorBusNum());
            dto.setOnlineBusNum(rUploadEvaluationDataD2.getOnlineBusNum());
            dto.setMonitorBusRate(rUploadEvaluationDataD2.getMonitorBusRate());
            result.add(dto);
        }
    }

    /**
     * 获取单位母线的均值数据
     */
    public RDimVoltageD getDimVoltageData(String orgId, String time, String voltage,String dataType) {
        LambdaQueryWrapper<RDimVoltageD> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(RDimVoltageD::getOrgId, orgId)
                .eq(RDimVoltageD::getStatisDate, time)
                .eq(RDimVoltageD::getVoltageType, voltage)
        .eq(RDimVoltageD::getDataType,dataType);
        return rDimVoltageDMapper.selectOne(lambdaQueryWrapper);
    }

    /**
     * 获取不同电压等级母线下的监测点数据，用于计算标准差
     */
    public Double getDimVoltageDataSd(String voltage, Double avg, String time, List<Monitor> line, String type, Integer times) {
        double standardDeviation = 3.1415926;
        if (Objects.equals(avg, standardDeviation)) {
            return standardDeviation;
        }
        //获取监测点数据
        if (CollUtil.isNotEmpty(line)) {
            Map<String, List<Monitor>> map = line.stream().collect(Collectors.groupingBy(Monitor::getVoltageLevel));
            if (!Objects.isNull(map.get(voltage))) {
                Set<String> lineSet = map.get(voltage).stream().map(Monitor::getId).collect(Collectors.toSet());
                List<LineDataDto> dataList = rDimVoltageDMapper.getLineData(time, time, lineSet);


                //根据平均值计算每个指标的标准差
                if (CollUtil.isNotEmpty(dataList)) {
                    double total = this.getDataByType(type, avg, dataList, times);
                    //计算标准差
                    standardDeviation = Math.sqrt(total / dataList.size());
                }

            }
        }
        return standardDeviation;
    }

    /**
     * 不同指标标准差算法
     */
    public Double getDataByType(String type, Double avg, List<LineDataDto> dataList, Integer times) {
        double total = 0.0;
        switch (type) {
            case "01":
                for (LineDataDto lineDataDto : dataList) {
                    total += (lineDataDto.getRms() - avg) * (lineDataDto.getRms() - avg);
                }
                return total;
            case "02":
                for (LineDataDto lineDataDto : dataList) {
                    total += (lineDataDto.getPst() - avg) * (lineDataDto.getPst() - avg);
                }
                return total;
            case "03":
                for (LineDataDto lineDataDto : dataList) {
                    total += (lineDataDto.getVUnbalance() - avg) * (lineDataDto.getVUnbalance() - avg);
                }
                return total;
            case "04":
                for (LineDataDto lineDataDto : dataList) {
                    total += (lineDataDto.getVThd() - avg) * (lineDataDto.getVThd() - avg);
                }
                return total;
            case "05":
                for (LineDataDto lineDataDto : dataList) {
                    try {
                        double value = (double) lineDataDto.getClass().getMethod("getV" + times).invoke(lineDataDto);
                        total += (value - avg) * (value - avg);
                    } catch (Exception e) {
                        log.error(e.getMessage());
                    }
                }
                return total;
            case "06":
                for (LineDataDto lineDataDto : dataList) {
                    total += (lineDataDto.getINeg() - avg) * (lineDataDto.getINeg() - avg);
                }
                return total;
            default:
                return 3.1415926;
        }
    }


}
