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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
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.DeptGetBase;
import com.njcn.device.biz.pojo.dto.DeptGetBusBarDTO;
import com.njcn.device.biz.pojo.dto.DeptGetChildrenMoreDTO;
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.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.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.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.util.*;
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;

    @Override
    public void insertEvaluationDataDay(CalculatedParam<DeptGetChildrenMoreDTO> calculatedParam) {
        List<RUploadEvaluationDataD> result = new ArrayList<>();
        final Double defaultValue = 3.1415926;
        //获取监测点信息
        List<Monitor> list1 = this.getPmsMonitor();
        //获取中台母线信息
        List<PmsMidLedger> list2 = this.getBusBarInfo();
        //获取灿能母线信息
        List<GeneratrixWire> 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 = this.getBusBarNum(list3,list2,barDto);
        List<BusBarDto> allDept = this.getAllDeptLineNum(busBarList,deptGetLineParam);
        //获取省级单位id
        String provinceId = deptFeignClient.getDepSonIdByDeptId(data.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())){
                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.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);

            BusBarDto busBarDto = allDept.stream().filter(o->Objects.equals(o.getOrgId(),item.getUnitId())).findFirst().orElse(null);
            //fixme 这边均值和标准差算法较为复杂，同时国网不要求上送，暂不计算
            /*** 计算无电压等级的数据*/
            RUploadEvaluationDataD dto = this.getLineNum(busBarDto,"0");
            //电压
            RUploadEvaluationDataD dto1 = this.channelData(rUploadEvaluationDataD,defaultValue,UploadEnum.INDEX_TYPE_01.getCode(),0,"0",dto);
            result.add(dto1);
            //长时间闪变
            RUploadEvaluationDataD dto2 = this.channelData(rUploadEvaluationDataD,defaultValue,UploadEnum.INDEX_TYPE_02.getCode(),0,"0",dto);
            result.add(dto2);
            //三相电压不平衡
            RUploadEvaluationDataD dto3 = this.channelData(rUploadEvaluationDataD,defaultValue,UploadEnum.INDEX_TYPE_03.getCode(),0,"0",dto);
            result.add(dto3);
            //电压总谐波畸变率
            RUploadEvaluationDataD dto4 = this.channelData(rUploadEvaluationDataD,defaultValue,UploadEnum.INDEX_TYPE_04.getCode(),0,"0",dto);
            result.add(dto4);
            //各次谐波电压
            this.channelHarmonicData(rUploadEvaluationDataD,result,null,UploadEnum.INDEX_TYPE_05.getCode(),"0",dto);
            //负序电流
            RUploadEvaluationDataD dto6 = this.channelData(rUploadEvaluationDataD,defaultValue,UploadEnum.INDEX_TYPE_06.getCode(),0,"0",dto);
            result.add(dto6);
            /*** 计算分电压等级的数据*/
            if (CollUtil.isNotEmpty(busBarDto.getVoltageChild())){
                busBarDto.getVoltageChild().forEach(item2->{
                    RUploadEvaluationDataD dto0 = this.getLineNum(busBarDto,item2.getVoltageLevel());
                    //电压
                    RUploadEvaluationDataD dto11 = this.channelData(rUploadEvaluationDataD,defaultValue,UploadEnum.INDEX_TYPE_01.getCode(),0,item2.getVoltageLevel(),dto0);
                    result.add(dto11);
                    //长时间闪变
                    RUploadEvaluationDataD dto22 = this.channelData(rUploadEvaluationDataD,defaultValue,UploadEnum.INDEX_TYPE_02.getCode(),0,item2.getVoltageLevel(),dto0);
                    result.add(dto22);
                    //三相电压不平衡
                    RUploadEvaluationDataD dto33 = this.channelData(rUploadEvaluationDataD,defaultValue,UploadEnum.INDEX_TYPE_03.getCode(),0,item2.getVoltageLevel(),dto0);
                    result.add(dto33);
                    //电压总谐波畸变率
                    RUploadEvaluationDataD dto44 = this.channelData(rUploadEvaluationDataD,defaultValue,UploadEnum.INDEX_TYPE_04.getCode(),0,item2.getVoltageLevel(),dto0);
                    result.add(dto44);
                    //各次谐波电压
                    this.channelHarmonicData(rUploadEvaluationDataD,result,null,UploadEnum.INDEX_TYPE_05.getCode(),item2.getVoltageLevel(),dto0);
                    //负序电流
                    RUploadEvaluationDataD dto66 = this.channelData(rUploadEvaluationDataD,defaultValue,UploadEnum.INDEX_TYPE_06.getCode(),0,item2.getVoltageLevel(),dto0);
                    result.add(dto66);
                });
            }
        });
        if (CollUtil.isNotEmpty(result)){
            this.saveOrUpdateBatchByMultiId(result,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() {
        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::getState, DataStateEnum.ENABLE.getCode())
                .in(PmsMidLedger::getVoltageLevel, list);
        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());
                    //这边没法直接通过电压等级来关联灿能母线，只能通过 Mid_Bus_Id 来关联
                    List<GeneratrixWire> l3 = list1.stream().filter(o->l2.contains(o.getMidBusId())).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();
                }
                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 = v.stream().mapToInt(BusBarDto.VoltageChild::getMonitorBusNum).sum();
                        c1.setMonitorBusNum(monitorBusNum);
                        int online = v.stream().mapToInt(BusBarDto.VoltageChild::getOnlineBusNum).sum();
                        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());
                    }
                });
            }
        }
        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, 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(value==3.1415926?3.1415926:0d);
        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, String indexType, String voltage,RUploadEvaluationDataD rUploadEvaluationDataD2) {
        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);
            dto.setStandardDeviation(CollUtil.isNotEmpty(valueList)?Objects.equals(valueList.get(i),defaultValue)?defaultValue:0d:defaultValue);
            dto.setVoltageLevel(voltage);
            dto.setMonitorBusNum(rUploadEvaluationDataD2.getMonitorBusNum());
            dto.setOnlineBusNum(rUploadEvaluationDataD2.getOnlineBusNum());
            dto.setMonitorBusRate(rUploadEvaluationDataD2.getMonitorBusRate());
            result.add(dto);
        }
    }
}