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.DeptGetChildrenMoreDTO;
import com.njcn.device.biz.pojo.dto.LineDevGetDTO;
import com.njcn.device.biz.pojo.param.DeptGetLineParam;
import com.njcn.device.pms.api.StatationStatClient;
import com.njcn.device.pms.pojo.param.PmsStatationStatInfoParam;
import com.njcn.device.pms.pojo.po.PmsMidLedger;
import com.njcn.device.pms.pojo.po.StatationStat;
import com.njcn.harmonic.pojo.po.upload.PmsRunStatisticM;
import com.njcn.harmonic.pojo.po.upload.PmsRunStatisticY;
import com.njcn.harmonic.pojo.po.upload.RUploadSubstationStatisticalDataD;
import com.njcn.prepare.harmonic.enums.UploadEnum;
import com.njcn.prepare.harmonic.mapper.mysql.dim.PmsMidLedgerMapper;
import com.njcn.prepare.harmonic.mapper.mysql.upload.RUploadSubstationStatisticalDataDMapper;
import com.njcn.prepare.harmonic.pojo.bo.CalculatedParam;
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.IRUploadSubstationStatisticalDataDService;
import com.njcn.user.api.DeptFeignClient;
import com.njcn.user.pojo.po.Dept;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 主配网变电站监测统计数据-日表 服务实现类
 * </p>
 *
 * @author xuyang
 * @since 2023-12-08
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class RUploadSubstationStatisticalDataDServiceImpl extends MppServiceImpl<RUploadSubstationStatisticalDataDMapper, RUploadSubstationStatisticalDataD> implements IRUploadSubstationStatisticalDataDService {

    private final DeptFeignClient deptFeignClient;
    private final StatationStatClient statationStatClient;
    private final PmsMidLedgerMapper pmsMidLedgerMapper;
    private final CommTerminalGeneralClient commTerminalGeneralClient;
    private final IPmsRunStatisticMService runStatisticMService;
    private final IPmsRunStatisticYService runStatisticYService;

    @Override
    public void insertSubStatisticalDataMonth(CalculatedParam<String> calculatedParam) {
        //起始时间
        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<RUploadSubstationStatisticalDataD> result = new ArrayList<>();
        //获取省级单位id
        Dept data = deptFeignClient.getRootDept().getData();
        String provinceId = deptFeignClient.getDepSonIdByDeptId(data.getId()).getData().get(0);
        Dept dept = deptFeignClient.getDeptById(provinceId).getData();
        //获取部门监测点关系
        DeptGetLineParam deptGetLineParam = new DeptGetLineParam();
        deptGetLineParam.setDeptId(data.getId());
        deptGetLineParam.setSystemType(0);
        List<DeptGetChildrenMoreDTO> deptGetChildrenList = commTerminalGeneralClient.deptGetLine(deptGetLineParam).getData();
        Map<String,List<DeptGetChildrenMoreDTO>> deptChildren = deptGetChildrenList.stream().collect(Collectors.groupingBy(DeptGetChildrenMoreDTO::getUnitId));
        //变电站id
        List<String> subList ;
        //获取月数据
        List<PmsRunStatisticM> pmsRunStatistics = runStatisticMService.selectListByDate(startTime, endTime,calculatedParam.getDataDate());
        Map<String, PmsRunStatisticM> pmsRunStatisticMap = pmsRunStatistics.stream().collect(Collectors.toMap(PmsRunStatisticM::getDeptId, Function.identity()));

        if (pmsRunStatisticMap.containsKey(dept.getCode())) {
            String onlineStationIds = pmsRunStatisticMap.get(dept.getCode()).getOnlineStationIds();
            if(StrUtil.isNotBlank(onlineStationIds)){
                subList = CollectionUtil.toList(onlineStationIds.split(StrUtil.COMMA));
            }else {
                subList = calculatedParam.getIdList();
            }
        } else {
            subList = calculatedParam.getIdList();
        }

        //获取监测变电站信息
        List<StatationStat> subInfo = getSubstationInfo(subList);
        Map<String,List<StatationStat>> subMap = subInfo.stream().collect(Collectors.groupingBy(StatationStat::getOrgId));
        //获取中台变电站信息
        List<PmsMidLedger> midSubInfo =  this.getSubstationInfo();
        Map<String,List<PmsMidLedger>> midSubMap = midSubInfo.stream().collect(Collectors.groupingBy(PmsMidLedger::getSectionId));
        //获取所有部门单位信息
        List<Dept> deptList = deptFeignClient.getAllDept().getData();
        Map<String,List<Dept>> deptMap = deptList.stream().collect(Collectors.groupingBy(Dept::getCode));
        deptMap.forEach((k,v)->{
            List<String> list = Arrays.stream(v.get(0).getPids().split(",")).map(String::trim).collect(Collectors.toList());
            if (list.size() > 1){
                RUploadSubstationStatisticalDataD rUploadSubstationStatisticalDataD = new RUploadSubstationStatisticalDataD();
                rUploadSubstationStatisticalDataD.setId(IdUtil.simpleUUID());
                rUploadSubstationStatisticalDataD.setStatisticalDate(DateUtil.format(DateUtil.parse(calculatedParam.getDataDate()),DatePattern.NORM_MONTH_PATTERN));
                rUploadSubstationStatisticalDataD.setComputeDate(calculatedParam.getDataDate());
                rUploadSubstationStatisticalDataD.setStatisticalType(UploadEnum.STATISTICAL_TYPE_02.getCode());
                rUploadSubstationStatisticalDataD.setProvinceId(dept.getCode());
                rUploadSubstationStatisticalDataD.setProvinceName(dept.getName());
                rUploadSubstationStatisticalDataD.setUploadStatus(Integer.parseInt(UploadEnum.UPLOAD_STATUS_0.getCode()));

                if(pmsRunStatisticMap.containsKey(k)){
                    System.out.println("进入当前步骤++++++++++++++++++++");
                    String runMonitorIds = pmsRunStatisticMap.get(dept.getCode()).getRunMonitorIds();
                    if(StrUtil.isNotBlank(runMonitorIds)){
                        ArrayList<String> list1 = CollectionUtil.toList(runMonitorIds.split(StrUtil.COMMA));
                        rUploadSubstationStatisticalDataD.setOnlineMonitorNum(list1.size());
                    }else {
                        rUploadSubstationStatisticalDataD.setOnlineMonitorNum(0);
                    }
                }else{
                    //计算在线监测点数
                    System.out.println("临时测试---------------"+deptChildren.size());
                    List<LineDevGetDTO> l = deptChildren.get(k).get(0).getLineBaseList();

                    if (CollUtil.isNotEmpty(l)){
                        l = l.stream().filter(o->Objects.equals(o.getIsUpToGrid(),1)).collect(Collectors.toList());
                        rUploadSubstationStatisticalDataD.setOnlineMonitorNum(l.size());
                    } else {
                        rUploadSubstationStatisticalDataD.setOnlineMonitorNum(0);
                    }
                }

                //处理层级关系 && 处理基础数据
                this.getDeptLevel(list,rUploadSubstationStatisticalDataD,deptList,deptMap,k,subMap,midSubMap);
                result.add(rUploadSubstationStatisticalDataD);
            }
        });
        if (CollectionUtil.isNotEmpty(result)){
            //查询数据如果有数据,将data_id置为null,这样就保留之前的唯一id
            LambdaQueryWrapper<RUploadSubstationStatisticalDataD> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(RUploadSubstationStatisticalDataD::getStatisticalDate,calculatedParam.getDataDate());
            List<RUploadSubstationStatisticalDataD> oldData = this.list(lambdaQueryWrapper);
            if (CollectionUtil.isNotEmpty(oldData)){
                result.forEach(item->{
                    item.setId(null);
                });
            }
            //存储数据
            this.saveOrUpdateBatchByMultiId(result);
        }
    }

    @Override
    public void insertSubStatisticalDataYear(CalculatedParam<String> calculatedParam) {
        //开始月份
        String beginMonth = DateUtil.format(DateUtil.beginOfMonth(DateUtil.parse(calculatedParam.getDataDate(), DatePattern.NORM_MONTH_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<RUploadSubstationStatisticalDataD> list = this.baseMapper.substationStatisticalMonthData(beginMonth,startTime,endTime);

        List<PmsRunStatisticY> pmsRunStatistics = runStatisticYService.selectListByDate(startTime, endTime,calculatedParam.getDataDate());
        Map<String, PmsRunStatisticY> pmsRunStatisticMap = pmsRunStatistics.stream().collect(Collectors.toMap(PmsRunStatisticY::getDeptId, Function.identity()));
        //数据分组
        Map<String, List<RUploadSubstationStatisticalDataD>> listMap = list.stream().collect(Collectors.groupingBy(x ->{
                    String str = "";
                    if(StrUtil.isNotBlank(x.getProvinceId())){
                        str = x.getProvinceId();
                    }
                    if(StrUtil.isNotBlank(x.getCityId())){
                        str = x.getCityId();
                    }
                    if(StrUtil.isNotBlank(x.getCountyId())){
                        str = x.getCountyId();
                    }
                    return str;
            }
        ));
        listMap.forEach((key,value)->{
            if(pmsRunStatisticMap.containsKey(key)){
                PmsRunStatisticY pmsRunStatistic = pmsRunStatisticMap.get(key);
                String runMonitorIds = pmsRunStatistic.getRunMonitorIds();
                if(StrUtil.isNotBlank(runMonitorIds)){
                    ArrayList<String> list1 = CollectionUtil.toList(runMonitorIds.split(StrUtil.COMMA));
                    value.forEach(item->{
                        item.setOnlineMonitorNum(list1.size());
                        item.setMonitoringRate(Objects.isNull(item.getSubstationCount())?null:list1.size()*1.0/item.getSubstationCount()*100);
                    });

                }

            }
        });

        if (CollUtil.isNotEmpty(list)){
            list.forEach(item->{
                item.setId(IdUtil.simpleUUID());
                item.setComputeDate(calculatedParam.getDataDate());
            });
            this.saveOrUpdateBatchByMultiId(list,1000);
        }

    }

    /**
     * 获取中台电站信息
     */
    public List<PmsMidLedger> getSubstationInfo() {
        LambdaQueryWrapper<PmsMidLedger> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(PmsMidLedger::getLevel, DataStateEnum.DELETED.getCode())
                .eq(PmsMidLedger::getState, DataStateEnum.ENABLE.getCode());
        return pmsMidLedgerMapper.selectList(lambdaQueryWrapper);
    }

    /**
     * 获取变电站信息
     * @param list
     * @return
     */
    public List<StatationStat> getSubstationInfo(List<String> list) {
        PmsStatationStatInfoParam param = new PmsStatationStatInfoParam();
        param.setPowerIds(list);
        return statationStatClient.getPowerInfo(param).getData();
    }

    /**
     * 判断当前部门的层级
     * @return
     */
    public void getDeptLevel(List<String> list,
                             RUploadSubstationStatisticalDataD rUploadSubstationStatisticalDataD,
                             List<Dept> deptList,
                             Map<String,List<Dept>> map,
                             String code,
                             Map<String,List<StatationStat>> subMap,
                             Map<String,List<PmsMidLedger>> midSubMap) {
        switch (list.size()) {
            //省级
            case 2:
                rUploadSubstationStatisticalDataD.setCityId("");
                rUploadSubstationStatisticalDataD.setCountyId("");
                int ct = 0;
                int ct2 = 0;
                //处理基础数据
                String i = deptList.stream().filter(o->Objects.equals(o.getCode(),code)).findAny().orElse(null).getId();
                List<String> cList = deptList.stream().filter(o->Objects.equals(o.getPid(),i)).map(Dept::getCode).collect(Collectors.toList());
                List<String> idList = deptList.stream().filter(o->Objects.equals(o.getPid(),i)).map(Dept::getId).collect(Collectors.toList());
                List<String> cList2 = deptList.stream().filter(o->idList.contains(o.getPid())).map(Dept::getCode).collect(Collectors.toList());
                List<String> cList3 = Stream.concat(cList.stream(), cList2.stream()).collect(Collectors.toList());
                for (String item : cList3) {
                    List<StatationStat> l = subMap.get(item);
                    if (CollectionUtil.isNotEmpty(l)){
                        ct = ct + l.size();
                    }
                    List<PmsMidLedger> l2 = midSubMap.get(item);
                    if (CollectionUtil.isNotEmpty(l2)){
                        ct2 = ct2 + l2.size();
                    }
                }
                rUploadSubstationStatisticalDataD.setSubstationCount(ct2 == 0 ? null:ct2);
                rUploadSubstationStatisticalDataD.setRunSubstationNum(ct2 == 0 ? null:ct2);
                rUploadSubstationStatisticalDataD.setMonitorSubstaionNum(ct == 0 ? null:ct);
                rUploadSubstationStatisticalDataD.setMonitoringRate(Objects.isNull(rUploadSubstationStatisticalDataD.getSubstationCount())?null:ct*1.0/rUploadSubstationStatisticalDataD.getSubstationCount()*100);
                break;
            //市级
            case 3:
                int count = 0;
                int count2 = 0;
                //处理层级
                rUploadSubstationStatisticalDataD.setCityId(code);
                rUploadSubstationStatisticalDataD.setCityName(map.get(code).get(0).getName());
                rUploadSubstationStatisticalDataD.setCountyId("");
                //处理基础数据
                String id = deptList.stream().filter(o->Objects.equals(o.getCode(),code)).findAny().orElse(null).getId();
                List<String> codeList = deptList.stream().filter(o->Objects.equals(o.getPid(),id)).map(Dept::getCode).collect(Collectors.toList());
                for (String item : codeList) {
                    List<StatationStat> l = subMap.get(item);
                    if (CollectionUtil.isNotEmpty(l)){
                        count = count + l.size();
                    }
                    List<PmsMidLedger> l2 = midSubMap.get(item);
                    if (CollectionUtil.isNotEmpty(l2)){
                        count2 = count2 + l2.size();
                    }
                }
                rUploadSubstationStatisticalDataD.setSubstationCount(count2 == 0 ? null:count2);
                rUploadSubstationStatisticalDataD.setRunSubstationNum(count2 == 0 ? null:count2);
                rUploadSubstationStatisticalDataD.setMonitorSubstaionNum(count == 0 ? null:count);
                rUploadSubstationStatisticalDataD.setMonitoringRate(Objects.isNull(rUploadSubstationStatisticalDataD.getSubstationCount())?null:count*1.0/rUploadSubstationStatisticalDataD.getSubstationCount()*100);
                break;
            //县级
            case 4:
                int size = 0;
                //处理层级
                String parentCode = deptList.stream().filter(o->Objects.equals(o.getId(),list.get(3))).findFirst().orElse(null).getCode();
                rUploadSubstationStatisticalDataD.setCityId(parentCode);
                rUploadSubstationStatisticalDataD.setCityName(map.get(parentCode).get(0).getName());
                rUploadSubstationStatisticalDataD.setCountyId(code);
                rUploadSubstationStatisticalDataD.setCountyName(map.get(code).get(0).getName());
                //处理基础数据
                List<StatationStat> l = subMap.get(code);
                List<PmsMidLedger> l2 = midSubMap.get(code);
                if (CollectionUtil.isNotEmpty(l)){
                    rUploadSubstationStatisticalDataD.setMonitorSubstaionNum(l.size());
                    size = l.size();
                } else {
                    rUploadSubstationStatisticalDataD.setMonitorSubstaionNum(0);
                }
                if (CollectionUtil.isNotEmpty(l2)){
                    rUploadSubstationStatisticalDataD.setSubstationCount(l2.size());
                    rUploadSubstationStatisticalDataD.setRunSubstationNum(l2.size());
                }
                rUploadSubstationStatisticalDataD.setMonitoringRate(Objects.isNull(rUploadSubstationStatisticalDataD.getSubstationCount())?null: size * 1.0 / rUploadSubstationStatisticalDataD.getSubstationCount() * 100);
                break;
            default:
                break;
        }
    }
}
