package com.njcn.process.service.impl;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.date.TimeInterval;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.jeffreyning.mybatisplus.service.MppServiceImpl;
import com.njcn.common.utils.PubUtils;
import com.njcn.device.biz.commApi.CommLedgerDeptClient;
import com.njcn.device.biz.commApi.CommTerminalGeneralClient;
import com.njcn.device.biz.pojo.dto.DeptGetBase;
import com.njcn.device.biz.pojo.param.DeptGetLineParam;
import com.njcn.process.mapper.SupvReportMMapper;
import com.njcn.process.pojo.dto.ProcessPublicDTO;
import com.njcn.process.pojo.po.SupvReportM;
import com.njcn.process.service.ISupvReportMService;
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 com.njcn.user.pojo.vo.PvTerminalTreeVO;
import com.njcn.web.factory.PageFactory;
import com.njcn.web.pojo.param.BaseParam;
import liquibase.pro.packaged.T;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author hongawen
 * @since 2023-06-26
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class SupvReportMServiceImpl extends MppServiceImpl<SupvReportMMapper, SupvReportM> implements ISupvReportMService {

    private final CommTerminalGeneralClient commTerminalGeneralClient;

    private final DeptFeignClient deptFeignClient;

    private final DicDataFeignClient dicDataFeignClient;

    @Override
    @Async("asyncExecutor")
    public void statisticSuperviseReport(LocalDate timeId) {
        log.info(LocalDateTime.now()+"_________________________开始执行");
        TimeInterval timeInterval = new TimeInterval();

        //当月第一天
        LocalDateTime firstDay = timeId.with(TemporalAdjusters.firstDayOfMonth()).atTime(0,0,0);

        //当年第一天
        LocalDateTime firstYearDay = timeId.with(TemporalAdjusters.firstDayOfYear()).atTime(0,0,0);

        //年度最后一天
        LocalDateTime endYearDay = timeId.with(TemporalAdjusters.lastDayOfYear()).atTime(23,59,59);


        //当前统计时间
        LocalDateTime endTime = timeId.atTime(23,59,59);

        List<DictData> dictDataUhv = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.SUPV_TYPE.getCode()).getData();
        Map<String,DictData> mapStatistic = dictDataUhv.stream().collect(Collectors.toMap(DictData::getCode, Function.identity()));
        DeptGetLineParam deptGetLineParam = new DeptGetLineParam();
        deptGetLineParam.setDeptId(deptFeignClient.getRootDept().getData().getId());
        List<DeptGetBase> deptGetBaseList = commTerminalGeneralClient.getDeptChildrenByParent(deptGetLineParam).getData();

        List<PvTerminalTreeVO> deptList = deptFeignClient.allDeptList().getData();
        Map<String,PvTerminalTreeVO> mapCode = deptList.stream().collect(Collectors.toMap(PvTerminalTreeVO::getCode, Function.identity()));
        Map<String,PvTerminalTreeVO> mapList = deptList.stream().collect(Collectors.toMap(PvTerminalTreeVO::getId, Function.identity()));

        List<ProcessPublicDTO> processPublicDTOListM = this.baseMapper.statisticPlanReport(firstDay,endTime,mapStatistic.get(DicDataEnum.UHV_Converter.getCode()).getId(),null,Stream.of("02","03","04").collect(Collectors.toList()));
        List<ProcessPublicDTO> processPublicDTOListY = this.baseMapper.statisticPlanReport(firstYearDay,endYearDay,mapStatistic.get(DicDataEnum.UHV_Converter.getCode()).getId(),null,null);
        List<ProcessPublicDTO> processPublicDTOListAll = this.baseMapper.statisticPlanReport(firstYearDay,endTime,mapStatistic.get(DicDataEnum.UHV_Converter.getCode()).getId(),null, Stream.of("02","03","04").collect(Collectors.toList()));

        List<ProcessPublicDTO> processPublicDTOListNewM = this.baseMapper.statisticPlanReport(firstDay,endTime,mapStatistic.get(DicDataEnum.New_Energy.getCode()).getId(),null,Stream.of("02","03","04").collect(Collectors.toList()));
        List<ProcessPublicDTO> processPublicDTOListNewY = this.baseMapper.statisticPlanReport(firstYearDay,endYearDay,mapStatistic.get(DicDataEnum.New_Energy.getCode()).getId(),null,null);
        List<ProcessPublicDTO> processPublicDTOListNewAll = this.baseMapper.statisticPlanReport(firstYearDay,endTime,mapStatistic.get(DicDataEnum.New_Energy.getCode()).getId(),null,Stream.of("02","03","04").collect(Collectors.toList()));

        List<ProcessPublicDTO> processPublicDTOListNewZM = this.baseMapper.statisticPlanReport(firstDay,endTime,mapStatistic.get(DicDataEnum.New_Energy.getCode()).getId(),"02",Stream.of("02","03","04").collect(Collectors.toList()));
        List<ProcessPublicDTO> processPublicDTOListNewZY = this.baseMapper.statisticPlanReport(firstYearDay,endYearDay,mapStatistic.get(DicDataEnum.New_Energy.getCode()).getId(),"02",null);
        List<ProcessPublicDTO> processPublicDTOListNewZAll = this.baseMapper.statisticPlanReport(firstYearDay,endTime,mapStatistic.get(DicDataEnum.New_Energy.getCode()).getId(),"02",Stream.of("02","03","04").collect(Collectors.toList()));


        //换流站问题总数量
        List<ProcessPublicDTO> processPublicDTOQesM = this.baseMapper.statisticQueReport(firstDay,endTime,mapStatistic.get(DicDataEnum.UHV_Converter.getCode()).getId(),null,null);
        List<ProcessPublicDTO> processPublicDTOQesAll = this.baseMapper.statisticQueReport(firstYearDay,endTime,mapStatistic.get(DicDataEnum.UHV_Converter.getCode()).getId(),null,null);

        //换流站问题已整改数量
        List<ProcessPublicDTO> processPublicDTOQesYesM = this.baseMapper.statisticQueReport(firstDay,endTime,mapStatistic.get(DicDataEnum.UHV_Converter.getCode()).getId(),"01",null);
        List<ProcessPublicDTO> processPublicDTOQesYesAll = this.baseMapper.statisticQueReport(firstYearDay,endTime,mapStatistic.get(DicDataEnum.UHV_Converter.getCode()).getId(),"01",null);

        //新能源问题总数量
        List<ProcessPublicDTO> processPublicDTOQesNewM = this.baseMapper.statisticQueReport(firstDay,endTime,mapStatistic.get(DicDataEnum.New_Energy.getCode()).getId(),null,null);
        List<ProcessPublicDTO> processPublicDTOQesNewAll = this.baseMapper.statisticQueReport(firstYearDay,endTime,mapStatistic.get(DicDataEnum.New_Energy.getCode()).getId(),null,null);

        //新能源问题已整改数量
        List<ProcessPublicDTO> processPublicDTOQesNewYesM = this.baseMapper.statisticQueReport(firstDay,endTime,mapStatistic.get(DicDataEnum.New_Energy.getCode()).getId(),"01",null);
        List<ProcessPublicDTO> processPublicDTOQesNewYesAll = this.baseMapper.statisticQueReport(firstYearDay,endTime,mapStatistic.get(DicDataEnum.New_Energy.getCode()).getId(),"01",null);

        //新能源改扩建问题数量
        List<ProcessPublicDTO> processPublicDTOQesNewGaiM = this.baseMapper.statisticQueReport(firstDay,endTime,mapStatistic.get(DicDataEnum.New_Energy.getCode()).getId(),null,"02");
        List<ProcessPublicDTO> processPublicDTOQesNewGaiAll = this.baseMapper.statisticQueReport(firstYearDay,endTime,mapStatistic.get(DicDataEnum.New_Energy.getCode()).getId(),null,"02");

        List<ProcessPublicDTO> processPublicDTOQesNewGaiYesM = this.baseMapper.statisticQueReport(firstDay,endTime,mapStatistic.get(DicDataEnum.New_Energy.getCode()).getId(),"01","02");
        List<ProcessPublicDTO> processPublicDTOQesNewGaiYesAll = this.baseMapper.statisticQueReport(firstYearDay,endTime,mapStatistic.get(DicDataEnum.New_Energy.getCode()).getId(),"01","02");


        //敏感用户
        List<ProcessPublicDTO> processPublicDTOMingGanM = this.baseMapper.statisticPlanReport(firstDay,endTime,mapStatistic.get(DicDataEnum.POWER_QUALITY.getCode()).getId(),null,Stream.of("02","03","04").collect(Collectors.toList()));
        List<ProcessPublicDTO> processPublicDTOMingGanY = this.baseMapper.statisticPlanReport(firstYearDay,endYearDay,mapStatistic.get(DicDataEnum.POWER_QUALITY.getCode()).getId(),null,null);
        List<ProcessPublicDTO> processPublicDTOMingGanAll = this.baseMapper.statisticPlanReport(firstYearDay,endTime,mapStatistic.get(DicDataEnum.POWER_QUALITY.getCode()).getId(),null,Stream.of("02","03","04").collect(Collectors.toList()));

        //换流站问题总数量
        List<ProcessPublicDTO> processPublicDTOQesMingGanM = this.baseMapper.statisticQueReport(firstDay,endTime,mapStatistic.get(DicDataEnum.POWER_QUALITY.getCode()).getId(),null,null);
        List<ProcessPublicDTO> processPublicDTOQesMingGanAll = this.baseMapper.statisticQueReport(firstYearDay,endTime,mapStatistic.get(DicDataEnum.POWER_QUALITY.getCode()).getId(),null,null);

        //换流站问题已整改数量
        List<ProcessPublicDTO> processPublicDTOQesMingGanYesM = this.baseMapper.statisticQueReport(firstDay,endTime,mapStatistic.get(DicDataEnum.POWER_QUALITY.getCode()).getId(),"01",null);
        List<ProcessPublicDTO> processPublicDTOQesMingGanYesAll = this.baseMapper.statisticQueReport(firstYearDay,endTime,mapStatistic.get(DicDataEnum.POWER_QUALITY.getCode()).getId(),"01",null);

        //电压
        List<ProcessPublicDTO> processPublicDTODianYaListM = this.baseMapper.statisticPlanReport(firstYearDay,endTime,mapStatistic.get(DicDataEnum.Technical_Super.getCode()).getId(),null,null);
        List<ProcessPublicDTO> processPublicDTODianYaListAll = this.baseMapper.statisticPlanReport(firstYearDay,endTime,mapStatistic.get(DicDataEnum.Technical_Super.getCode()).getId(),null,Stream.of("02","03","04").collect(Collectors.toList()));

        //本月问题数量和累计问题数量
        List<ProcessPublicDTO> processPublicDTODianYaGanM = this.baseMapper.statisticQueReport(firstDay,endTime,mapStatistic.get(DicDataEnum.Technical_Super.getCode()).getId(),null,null);
        List<ProcessPublicDTO> processPublicDTODianYaGanAll = this.baseMapper.statisticQueReport(firstYearDay,endTime,mapStatistic.get(DicDataEnum.Technical_Super.getCode()).getId(),null,null);
        List<ProcessPublicDTO> processPublicDTODianYaGanYesM = this.baseMapper.statisticQueReport(firstDay,endTime,mapStatistic.get(DicDataEnum.Technical_Super.getCode()).getId(),"01",null);
        List<ProcessPublicDTO> processPublicDTODianYaGanYesAll = this.baseMapper.statisticQueReport(firstYearDay,endTime,mapStatistic.get(DicDataEnum.Technical_Super.getCode()).getId(),"01",null);


        List<SupvReportM> supvReportMBatch = new ArrayList<>();
        for(DeptGetBase deptGetBase : deptGetBaseList){

            if(deptGetBase.getUnitName().equals("国家电网公司")){
                System.out.println(55);
            }
            if(deptGetBase.getDeptLevel() !=2 && deptGetBase.getDeptLevel() !=3 && deptGetBase.getDeptLevel() !=4){
                continue;
            }
            Integer all = 0;
            SupvReportM supvReportM = new SupvReportM();
            supvReportM.setStatisticsDate(timeId.with(TemporalAdjusters.firstDayOfMonth()));
            supvReportM.setStatisticsDept(deptGetBase.getUnitId());

            List<String> childrenDeptList = deptGetBase.getUnitChildrenList();
            if(CollUtil.isNotEmpty(childrenDeptList)){
                supvReportM.setConvertMonthSupvNum(dealData(childrenDeptList,processPublicDTOListM));
                supvReportM.setConvertYearSupvNum(dealData(childrenDeptList,processPublicDTOListY));

                Integer a = dealData(childrenDeptList,processPublicDTOListAll);
                supvReportM.setConvertTotalSupvNum(a);
                all+=a;
                supvReportM.setEnergyMonthSupvNum(dealData(childrenDeptList,processPublicDTOListNewM));
                supvReportM.setEnergyYearSupvNum(dealData(childrenDeptList,processPublicDTOListNewY));

                Integer b = dealData(childrenDeptList,processPublicDTOListNewAll);
                supvReportM.setEnergyTotalSupvNum(b);
                all+=b;

                supvReportM.setEnergyMonthSupvNewNum(dealData(childrenDeptList,processPublicDTOListNewZM));
                supvReportM.setEnergyYearSupvNewNum(dealData(childrenDeptList,processPublicDTOListNewZY));
                supvReportM.setEnergyTotalSupvNewNum(dealData(childrenDeptList,processPublicDTOListNewZAll));



                supvReportM.setConvertMonthQuesNum(dealData(childrenDeptList,processPublicDTOQesM));
                supvReportM.setConvertTotalQuesNum(dealData(childrenDeptList,processPublicDTOQesAll));

                supvReportM.setConvertMonthReformNum(dealData(childrenDeptList,processPublicDTOQesYesM));
                supvReportM.setConvertTotalReformNum(dealData(childrenDeptList,processPublicDTOQesYesAll));

                supvReportM.setEnergyMonthQuesNum(dealData(childrenDeptList,processPublicDTOQesNewM));
                supvReportM.setEnergyTotalQuesNum(dealData(childrenDeptList,processPublicDTOQesNewAll));

                supvReportM.setEnergyMonthReformNum(dealData(childrenDeptList,processPublicDTOQesNewYesM));
                supvReportM.setEnergyTotalReformNum(dealData(childrenDeptList,processPublicDTOQesNewYesAll));

                supvReportM.setEnergyMonthQuesNewNum(dealData(childrenDeptList,processPublicDTOQesNewGaiM));
                supvReportM.setEnergyTotalQuesNewNum(dealData(childrenDeptList,processPublicDTOQesNewGaiAll));

                supvReportM.setEnergyMonthReformNewNum(dealData(childrenDeptList,processPublicDTOQesNewGaiYesM));
                supvReportM.setEnergyTotalReformNewNum(dealData(childrenDeptList,processPublicDTOQesNewGaiYesAll));

                //敏感用户
                supvReportM.setSensitiveMonthSupvNum(dealData(childrenDeptList,processPublicDTOMingGanM));
                supvReportM.setSensitiveYearSupvNum(dealData(childrenDeptList,processPublicDTOMingGanY));

                Integer c = dealData(childrenDeptList,processPublicDTOMingGanAll);
                supvReportM.setSensitiveTotalSupvNum(c);
                all+=c;

                supvReportM.setSensitiveMonthQuesNum(dealData(childrenDeptList,processPublicDTOQesMingGanM));
                supvReportM.setSensitiveTotalQuesNum(dealData(childrenDeptList,processPublicDTOQesMingGanAll));

                supvReportM.setSensitiveMonthReformNum(dealData(childrenDeptList,processPublicDTOQesMingGanYesM));
                supvReportM.setSensitiveTotalReformNum(dealData(childrenDeptList,processPublicDTODianYaGanYesAll));

                //电压
                supvReportM.setPowerMonthPlanNum(dealData(childrenDeptList,processPublicDTODianYaListM));
                Integer d = dealData(childrenDeptList,processPublicDTODianYaListAll);
                supvReportM.setPowerMonthConductedNum(d);

                supvReportM.setPowerMonthQuesNum(dealData(childrenDeptList,processPublicDTODianYaGanM));
                supvReportM.setPowerTotalQuesNum(dealData(childrenDeptList,processPublicDTODianYaGanAll));
                supvReportM.setPowerMonthReformNum(dealData(childrenDeptList,processPublicDTODianYaGanYesM));
                supvReportM.setPowerTotalReformNum(dealData(childrenDeptList,processPublicDTODianYaGanAll));

                all+=d;

            }

            if(deptGetBase.getDeptLevel() == 2){
                //省级
                supvReportM.setProvinceId(deptGetBase.getUnitId());
                supvReportM.setProvinceName(deptGetBase.getUnitName());


                supvReportM.setStatisticsLevel("3");
            }else if(deptGetBase.getDeptLevel() == 3){
                //市
                PvTerminalTreeVO pvTerminalTreeVOOne = mapCode.get(deptGetBase.getUnitId());
                if(Objects.nonNull(pvTerminalTreeVOOne)){
                   PvTerminalTreeVO pvTerminalTreeVOTwo = mapList.get(pvTerminalTreeVOOne.getPid());
                    supvReportM.setCityId(deptGetBase.getUnitId());
                    supvReportM.setCityName(deptGetBase.getUnitName());
                    supvReportM.setProvinceName(pvTerminalTreeVOTwo.getName());
                    supvReportM.setProvinceId(pvTerminalTreeVOTwo.getCode());
                }
                supvReportM.setStatisticsLevel("4");
            }else if(deptGetBase.getDeptLevel() == 4){
                //县
                PvTerminalTreeVO pvTerminalTreeVOOne = mapCode.get(deptGetBase.getUnitId());
                if(Objects.nonNull(pvTerminalTreeVOOne)) {
                    PvTerminalTreeVO pvTerminalTreeVOTwo = mapList.get(pvTerminalTreeVOOne.getPid());
                    if(Objects.nonNull(pvTerminalTreeVOTwo)){
                        PvTerminalTreeVO pvTerminalTreeVOThree = mapList.get(pvTerminalTreeVOTwo.getPid());
                        supvReportM.setCountyId(deptGetBase.getUnitId());
                        supvReportM.setCountyName(deptGetBase.getUnitName());
                        supvReportM.setCityId(pvTerminalTreeVOTwo.getCode());
                        supvReportM.setCityName(pvTerminalTreeVOTwo.getName());
                        supvReportM.setProvinceName(pvTerminalTreeVOThree.getName());
                        supvReportM.setProvinceId(pvTerminalTreeVOThree.getCode());
                    }

                }
                supvReportM.setStatisticsLevel("5");
            }
            supvReportM.setSupvNum(all);
            //特殊处理每月第一天需要处理上送国网标识
            if(timeId.getDayOfMonth() == 1){
                supvReportM.setIsUploadHead(0);
            }
            supvReportMBatch.add(supvReportM);

        }

        this.saveOrUpdateBatchByMultiId(supvReportMBatch);

        log.info(LocalDateTime.now()+"_________________________执行时长："+timeInterval.interval());
    }

    @Override
    public Page<SupvReportM> statisticReportPage(BaseParam baseParam) {
        List<String> deptCodes = new ArrayList<>();
        if(StrUtil.isNotBlank(baseParam.getSearchValue())){
            List<Dept>deptList = deptFeignClient.getDirectSonSelf(baseParam.getSearchValue()).getData();
            deptCodes = deptList.stream().map(Dept::getCode).collect(Collectors.toList());
        }
        LambdaQueryWrapper<SupvReportM> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(StrUtil.isNotBlank(baseParam.getSearchValue()),SupvReportM::getStatisticsDept,deptCodes)
                .between(StrUtil.isNotBlank(baseParam.getSearchBeginTime()),SupvReportM::getStatisticsDate,baseParam.getSearchBeginTime(),baseParam.getSearchEndTime());
        return this.page(new Page<>(PageFactory.getPageNum(baseParam),PageFactory.getPageSize(baseParam)),lambdaQueryWrapper);

    }


    private Integer dealData(List<String> childrenDeptList,List<ProcessPublicDTO> processPublicDTOList){
        Integer count = 0;
        for(ProcessPublicDTO processPublicDTO :processPublicDTOList) {
            if (childrenDeptList.contains(processPublicDTO.getId())) {
                count += processPublicDTO.getValue();
            }
        }
        return count;
    }

}
