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


import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.jeffreyning.mybatisplus.service.MppServiceImpl;
import com.njcn.device.biz.pojo.dto.DeptGetChildrenDTO;
import com.njcn.device.pms.pojo.po.Monitor;
import com.njcn.device.pms.pojo.po.PmsCountLedger;
import com.njcn.harmonic.pojo.po.dim.RDimMonitorRateD;
import com.njcn.prepare.harmonic.mapper.mysql.area.PmsMonitorPOMapper;
import com.njcn.prepare.harmonic.mapper.mysql.dim.PmsCountLedgerMapper;
import com.njcn.prepare.harmonic.mapper.mysql.dim.RDimMonitorRateDMapper;
import com.njcn.prepare.harmonic.mapper.mysql.line.ROperatingMonitorDMapper;
import com.njcn.prepare.harmonic.pojo.bo.CalculatedParam;
import com.njcn.prepare.harmonic.pojo.mysql.ROperatingMonitorDPO;
import com.njcn.prepare.harmonic.service.mysql.dim.IRDimMonitorRateDService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author cdf
 * @since 2023-11-23
 */
@Service
@RequiredArgsConstructor
public class RDimMonitorRateDServiceImpl extends MppServiceImpl<RDimMonitorRateDMapper, RDimMonitorRateD> implements IRDimMonitorRateDService {

    private final PmsCountLedgerMapper pmsCountLedgerMapper;

    private final ROperatingMonitorDMapper rOperatingMonitorDMapper;

    private final PmsMonitorPOMapper pmsMonitorPOMapper;

    @Override
    public void monitorRateDay(CalculatedParam<DeptGetChildrenDTO> calculatedParam) {
        List<RDimMonitorRateD> poList = new ArrayList<>();
        LocalDate date = LocalDate.parse(calculatedParam.getDataDate());

        List<PmsCountLedger> pmsMidLedgerList = pmsCountLedgerMapper.newDateData();
        Map<String, PmsCountLedger> map = pmsMidLedgerList.stream().collect(Collectors.toMap(PmsCountLedger::getSection, Function.identity()));

        List<DeptGetChildrenDTO> deptList = calculatedParam.getIdList();
        for (DeptGetChildrenDTO dto : deptList) {
            Float busMonitorRate = 0f;
            Float stationMonitorRate = 0f;
            RDimMonitorRateD rDimMonitorRateD = new RDimMonitorRateD();
            rDimMonitorRateD.setOrgId(dto.getDeptId());
            rDimMonitorRateD.setStatisDate(date);

            List<String> monitorIds = dto.getLineIds();
            if (CollUtil.isEmpty(monitorIds)) {
                rDimMonitorRateD.setBusMonitorRate(busMonitorRate);
                rDimMonitorRateD.setStationMonitorRate(stationMonitorRate);
                poList.add(rDimMonitorRateD);
                continue;
            }

            if (map.containsKey(dto.getDeptId())) {
                PmsCountLedger pmsCountLedger = map.get(dto.getDeptId());
                Integer stationNum = pmsCountLedger.getSubCount();
                Integer busBarNum = pmsCountLedger.getSubvCount();

                LambdaQueryWrapper<ROperatingMonitorDPO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                lambdaQueryWrapper.eq(ROperatingMonitorDPO::getDataDate, date).in(ROperatingMonitorDPO::getMeasurementPointId, monitorIds);
                List<ROperatingMonitorDPO> rOperatingMonitorDPOList = rOperatingMonitorDMapper.selectList(lambdaQueryWrapper);


                List<ROperatingMonitorDPO> goodList = rOperatingMonitorDPOList.stream().filter(item -> item.getIsUnusual() == 0 && item.getIndexIntegrityRate().floatValue() >= 0.95).collect(Collectors.toList());
                List<String> ids = goodList.stream().map(ROperatingMonitorDPO::getMeasurementPointId).distinct().collect(Collectors.toList());
                if (CollUtil.isNotEmpty(ids)) {

                    List<Monitor> monitorList = pmsMonitorPOMapper.selectList(new LambdaQueryWrapper<Monitor>().in(Monitor::getId, ids));

                    if (busBarNum > 0) {
                        long count = monitorList.stream().map(Monitor::getLineId).distinct().count();
                        if (count > 0) {
                            busMonitorRate = (float) count / busBarNum;
                        }
                    }
                    if (stationNum > 0) {
                        long count = monitorList.stream().map(Monitor::getPowerrId).distinct().count();
                        if (count > 0) {
                            stationMonitorRate = (float) count / stationNum;
                        }
                    }
                }

            } else {
                rDimMonitorRateD.setBusMonitorRate(busMonitorRate);
                rDimMonitorRateD.setStationMonitorRate(stationMonitorRate);
                poList.add(rDimMonitorRateD);
                continue;
            }
            rDimMonitorRateD.setBusMonitorRate(busMonitorRate);
            rDimMonitorRateD.setStationMonitorRate(stationMonitorRate);
            poList.add(rDimMonitorRateD);
        }

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


    }
}
