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


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.jeffreyning.mybatisplus.service.MppServiceImpl;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.device.pms.api.MonitorClient;
import com.njcn.device.pms.pojo.param.MonitorParam;
import com.njcn.device.pms.pojo.po.*;
import com.njcn.device.pq.pojo.po.RStatIntegrityD;
import com.njcn.harmonic.pojo.po.upload.RUploadMainMonitorData;
import com.njcn.prepare.harmonic.mapper.mysql.day.RStatIntegrityDMapper;
import com.njcn.prepare.harmonic.mapper.mysql.upload.RUploadMainMonitorDataMapper;
import com.njcn.prepare.harmonic.service.mysql.upload.IRUploadMainMonitorDataService;
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 lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 公共连接点母线电能质量统计 服务实现类
 * </p>
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class RUploadMainMonitorDataServiceImpl extends MppServiceImpl<RUploadMainMonitorDataMapper, RUploadMainMonitorData> implements IRUploadMainMonitorDataService {

    private final MonitorClient monitorClient;

    private final DicDataFeignClient dicDataFeignClient;

    private final RStatIntegrityDMapper rStatIntegrityDMapper;






    @Override
    public void handlerDay(String date){

        LocalDate staDate = LocalDate.parse(date, DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN));

        MonitorParam monitorParam = new MonitorParam();
        monitorParam.setIsUpToGrid(DataStateEnum.ENABLE.getCode());

        DictData dictData = dicDataFeignClient.getDicDataByCodeAndType(DicDataEnum.RUN.getCode(),DicDataTypeEnum.LINE_STATE.getCode()).getData();
        monitorParam.setMonitorState(dictData.getId());
        List<Monitor> monitorList = monitorClient.getMonitorListByParam(monitorParam).getData();
        List<String> monitorIds = monitorList.stream().map(Monitor::getId).distinct().collect(Collectors.toList());

        LambdaQueryWrapper<RStatIntegrityD> integrityDLambda = new LambdaQueryWrapper<>();
        integrityDLambda.in(RStatIntegrityD::getLineIndex,monitorIds).eq(RStatIntegrityD::getTimeId,staDate);
        List<RStatIntegrityD> rStatIntegrityDList = rStatIntegrityDMapper.selectList(integrityDLambda);
        Map<String,RStatIntegrityD> inteMap = rStatIntegrityDList.stream().collect(Collectors.toMap(RStatIntegrityD::getLineIndex,Function.identity()));

        List<RUploadMainMonitorData> poList = new ArrayList<>();
        for(Monitor item : monitorList){

            RUploadMainMonitorData rUploadMainMonitorData = new RUploadMainMonitorData();
            rUploadMainMonitorData.setMonitorId(item.getMonitorId());
            rUploadMainMonitorData.setComputeDate(staDate);
            rUploadMainMonitorData.setObjId(IdUtil.simpleUUID());
            rUploadMainMonitorData.setStatisticalType(DicDataEnum.STATISTICAL_TYPE_D.getCode());
            rUploadMainMonitorData.setStatisticalDate(date);
            rUploadMainMonitorData.setUploadStatus(0);
            if(inteMap.containsKey(item.getId())){
                RStatIntegrityD rStatIntegrityD = inteMap.get(item.getId());
                if(rStatIntegrityD.getRealTime()>0){
                    rUploadMainMonitorData.setIsMonitorOnline(DicDataEnum.YES.getCode());
                    rUploadMainMonitorData.setIsTerminalOnline(DicDataEnum.YES.getCode());
                    rUploadMainMonitorData.setOnlineMonitorNum(1);
                    rUploadMainMonitorData.setRunMonitorNum(1);
                    BigDecimal rate = BigDecimal.valueOf((double)rStatIntegrityD.getRealTime()/rStatIntegrityD.getDueTime()).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP);
                    rUploadMainMonitorData.setOnlineMonitorRate(rate);
                    rUploadMainMonitorData.setExpectCollectNum((long)rStatIntegrityD.getDueTime());
                    rUploadMainMonitorData.setActualCollectNum((long)rStatIntegrityD.getRealTime());
                    rUploadMainMonitorData.setDataFullRate(rate);
                }else {
                    assLessEntity(rUploadMainMonitorData);
                }
            }else {
                assLessEntity(rUploadMainMonitorData);
            }
            poList.add(rUploadMainMonitorData);
        }

        if(CollUtil.isNotEmpty(poList)){
            this.saveOrUpdateBatchByMultiId(poList);
        }
    }


    public void handlerMonth(String date){
        String begin = DateUtil.format(DateUtil.beginOfMonth(DateUtil.parse(date,DatePattern.NORM_DATE_PATTERN)),DatePattern.NORM_DATE_PATTERN);

        QueryWrapper<RUploadMainMonitorData> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("monitor_id,max(is_Monitor_Online)  is_Monitor_Online,max(is_Terminal_Online) is_Terminal_Online,max(online_Monitor_Num) online_Monitor_Num,max(run_Monitor_Num) run_Monitor_Num,avg(online_Monitor_Rate) online_Monitor_Rate,sum(expect_Collect_Num) expect_Collect_Num,sum(actual_Collect_Num) actual_Collect_Num,avg(data_Full_Rate) data_Full_Rate")
                .eq("statistical_type",DicDataEnum.STATISTICAL_TYPE_D.getCode())
                .between("statistical_date",begin,date).groupBy("monitor_id");
        List<RUploadMainMonitorData> rUploadMainMonitorDataList = this.list(queryWrapper);
        if(CollUtil.isNotEmpty(rUploadMainMonitorDataList)){
            for(RUploadMainMonitorData item : rUploadMainMonitorDataList){
                item.setStatisticalType(DicDataEnum.STATISTICAL_TYPE_M.getCode());
                item.setUploadStatus(0);
                item.setObjId(IdUtil.simpleUUID());
                item.setStatisticalDate(date.substring(0,7));
                item.setComputeDate(LocalDate.parse(date,DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN)));
            }
            if(CollUtil.isNotEmpty(rUploadMainMonitorDataList)){
                this.saveOrUpdateBatchByMultiId(rUploadMainMonitorDataList);
            }
        }
    }


    public void handlerYear(String date){
        String begin = DateUtil.format(DateUtil.beginOfYear(DateUtil.parse(date,DatePattern.NORM_DATE_PATTERN)),DatePattern.NORM_DATE_PATTERN);

        QueryWrapper<RUploadMainMonitorData> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("monitor_id,max(is_Monitor_Online)  is_Monitor_Online,max(is_Terminal_Online) is_Terminal_Online,max(online_Monitor_Num) online_Monitor_Num,max(run_Monitor_Num) run_Monitor_Num,avg(online_Monitor_Rate) online_Monitor_Rate,sum(expect_Collect_Num) expect_Collect_Num,sum(actual_Collect_Num) actual_Collect_Num,avg(data_Full_Rate) data_Full_Rate")
                .eq("statistical_type",DicDataEnum.STATISTICAL_TYPE_M.getCode())
                .between("statistical_date",begin,date).groupBy("monitor_id");
        List<RUploadMainMonitorData> rUploadMainMonitorDataList = this.list(queryWrapper);
        if(CollUtil.isNotEmpty(rUploadMainMonitorDataList)){
            for(RUploadMainMonitorData item : rUploadMainMonitorDataList){
                item.setStatisticalType(DicDataEnum.STATISTICAL_TYPE_Y.getCode());
                item.setUploadStatus(0);
                item.setObjId(IdUtil.simpleUUID());
                item.setStatisticalDate(date.substring(0,4));
                item.setComputeDate(LocalDate.parse(date,DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN)));
            }
            if(CollUtil.isNotEmpty(rUploadMainMonitorDataList)){
                this.saveOrUpdateBatchByMultiId(rUploadMainMonitorDataList);
            }
        }
    }



    private void assLessEntity(RUploadMainMonitorData rUploadMainMonitorData){
        rUploadMainMonitorData.setIsMonitorOnline(DicDataEnum.NO.getCode());
        rUploadMainMonitorData.setIsTerminalOnline(DicDataEnum.NO.getCode());
        rUploadMainMonitorData.setOnlineMonitorNum(0);
        rUploadMainMonitorData.setRunMonitorNum(0);
        rUploadMainMonitorData.setOnlineMonitorRate(BigDecimal.ZERO);
        rUploadMainMonitorData.setExpectCollectNum((long)0);
        rUploadMainMonitorData.setActualCollectNum((long)0);
        rUploadMainMonitorData.setDataFullRate(BigDecimal.ZERO);
    }







}
