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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.jeffreyning.mybatisplus.service.MppServiceImpl;
import com.njcn.common.utils.PubUtils;
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.harmonic.pojo.po.ROperatingIndexMPO;
import com.njcn.prepare.harmonic.mapper.mysql.newalgorithm.RQualityParameterMMapper;
import com.njcn.prepare.harmonic.pojo.mysql.ROperatingMonitorDPO;
import com.njcn.prepare.harmonic.pojo.mysql.RQualityParameterM;
import com.njcn.prepare.harmonic.pojo.param.LineParam;
import com.njcn.prepare.harmonic.service.mysql.area.ROperatingIndexMPOService;
import com.njcn.prepare.harmonic.service.mysql.line.ROperatingMonitorService;
import com.njcn.prepare.harmonic.service.mysql.newalgorithm.RQualityParameterMService;
import com.njcn.system.api.DicDataFeignClient;
import com.njcn.system.enums.DicDataEnum;
import com.njcn.system.pojo.po.DictData;
import com.njcn.user.api.DeptFeignClient;
import com.njcn.user.pojo.po.Dept;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;


/**
 * <p>
 * 监测指标数据质量问题汇总统计-月表 服务实现类
 * </p>
 *
 * @author wr
 * @since 2023-10-09
 */
@Service
@RequiredArgsConstructor
public class RQualityParameterMServiceImpl extends MppServiceImpl<RQualityParameterMMapper, RQualityParameterM> implements RQualityParameterMService {

    private final ROperatingIndexMPOService rOperatingIndexMPOService;
    private final CommTerminalGeneralClient commTerminalGeneralClient;
    private final DeptFeignClient deptFeignClient;
    private final DicDataFeignClient dicDataFeignClient;
    private final ROperatingMonitorService rOperatingMonitorDService;
    @Override
    @Async("asyncExecutor")
    @Transactional(rollbackFor = {Exception.class})
    public void rQualityParameterMHandler(LineParam jobParam) {
        //获取主网id
        DictData data = dicDataFeignClient.getDicDataByCode(DicDataEnum.MAINNET_POINT.getCode()).getData();

        List<RQualityParameterM> info = new ArrayList();
        Dept dept = deptFeignClient.getRootDept().getData();
        DeptGetLineParam deptGetLineParam = new DeptGetLineParam();
        deptGetLineParam.setDeptId(dept.getId());
        List<DeptGetChildrenMoreDTO> deptGetBaseList = commTerminalGeneralClient.deptGetLine(deptGetLineParam).getData();
        //获取线路信息
        List<DeptGetBusBarDTO> busBarList = commTerminalGeneralClient.deptBusBar(deptGetLineParam).getData();
        Map<String, List<String>> busBarMap = busBarList.stream().collect(Collectors.toMap(DeptGetBusBarDTO::getUnitId, DeptGetBusBarDTO::getBusBarAndMonitorIDs));

        //获取线路信息
        List<DeptGetSubStationDTO> subStationList = commTerminalGeneralClient.deptSubStation(deptGetLineParam).getData();
        Map<String, List<String>> subStationMap = subStationList.stream().collect(Collectors.toMap(DeptGetSubStationDTO::getUnitId, DeptGetSubStationDTO::getStationAndMonitorIDs));


        //获取监测点数量和在运监测点
        List<ROperatingIndexMPO> list = rOperatingIndexMPOService.list(new LambdaQueryWrapper<ROperatingIndexMPO>()
                .ge(ROperatingIndexMPO::getDataDate, jobParam.getBeginTime())
                .le(ROperatingIndexMPO::getDataDate, jobParam.getEndTime())
        );


        Map<String, ROperatingIndexMPO> orgMonitorNumMap = list.stream().collect(Collectors.toMap(ROperatingIndexMPO::getOrgNo, Function.identity()));
        RQualityParameterM rQualityParameterM;
        for (DeptGetChildrenMoreDTO deptGetBase : deptGetBaseList) {
            rQualityParameterM = new RQualityParameterM();
            if (orgMonitorNumMap.containsKey(deptGetBase.getUnitId())) {
                ROperatingIndexMPO rOperatingIndexMPO = orgMonitorNumMap.get(deptGetBase.getUnitId());
                rQualityParameterM.setMeasurementCount(rOperatingIndexMPO.getMeasurementRunPoints());
                rQualityParameterM.setEffectiveAccessMeasurementCount(rOperatingIndexMPO.getEffectiveAccessMeasurementCount());
                //查询数据异常的监测点
                if(CollUtil.isNotEmpty(deptGetBase.getLineBaseList())){
                    List<String> lineIds = deptGetBase.getLineBaseList().stream().map(LineDevGetDTO::getPointId).distinct().collect(Collectors.toList());
                    int num = rOperatingMonitorDService.count(new LambdaQueryWrapper<ROperatingMonitorDPO>()
                            .in(ROperatingMonitorDPO::getMeasurementPointId, lineIds)
                            .eq(ROperatingMonitorDPO::getIsUnusual, 0)
                            .ge(ROperatingMonitorDPO::getDataDate, jobParam.getBeginTime())
                            .le(ROperatingMonitorDPO::getDataDate, jobParam.getEndTime())
                    );
                    rQualityParameterM.setProblem(num);
                }else{
                    rQualityParameterM.setProblem(0);
                }
                if(busBarMap.containsKey(deptGetBase.getUnitId())&&subStationMap.containsKey(deptGetBase.getUnitId())){
                    List<String> ids1 = busBarMap.get(deptGetBase.getUnitId());
                    List<String> ids2 = subStationMap.get(deptGetBase.getUnitId());
                    Integer sum = ids1.stream().filter(ids2::contains).collect(Collectors.toList()).size();
                    rQualityParameterM.setMatchingCount(sum);
                    Integer matchingCount = rQualityParameterM.getMatchingCount();
                    if(matchingCount!=null&&matchingCount!=0){
                        BigDecimal round = NumberUtil.round(sum / matchingCount * 1.0, 2);
                        rQualityParameterM.setMatchingRate(round.floatValue()*100);
                    }else{
                        rQualityParameterM.setMatchingCount(0);
                        rQualityParameterM.setMatchingRate(0.0f);
                    }
                }else{
                    rQualityParameterM.setMatchingCount(0);
                    rQualityParameterM.setMatchingRate(0.0f);
                }
            } else {
                rQualityParameterM.setMeasurementCount(0);
                rQualityParameterM.setEffectiveAccessMeasurementCount(0);
                rQualityParameterM.setProblem(0);
                rQualityParameterM.setMatchingCount(0);
                rQualityParameterM.setMatchingRate(0.0F);
            }
            rQualityParameterM.setMonitoringIntegrityRate(100.0F);
            rQualityParameterM.setDataDate(PubUtils.localDateTimeFormat(jobParam.getDataDate() + " " + "00:00:00"));
            rQualityParameterM.setOrgNo(deptGetBase.getUnitId());
            rQualityParameterM.setDataType(data.getId());

            info.add(rQualityParameterM);
        }
        if (CollUtil.isNotEmpty(info)) {
            this.saveOrUpdateBatchByMultiId(info, 500);
        }
    }
}
