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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.jeffreyning.mybatisplus.service.MppServiceImpl;
import com.njcn.device.biz.pojo.dto.DeptGetBusBarDTO;
import com.njcn.device.pms.pojo.po.GeneratrixWire;
import com.njcn.device.pms.pojo.po.Monitor;
import com.njcn.harmonic.pojo.po.dim.RDimVoltageD;
import com.njcn.prepare.harmonic.mapper.mysql.area.PmsMonitorPOMapper;
import com.njcn.prepare.harmonic.mapper.mysql.dim.GeneratrixWireMapper;
import com.njcn.prepare.harmonic.mapper.mysql.dim.RDimVoltageDMapper;
import com.njcn.prepare.harmonic.pojo.bo.CalculatedParam;
import com.njcn.harmonic.pojo.dto.LineDataDto;
import com.njcn.prepare.harmonic.service.mysql.dim.IRDimVoltageDService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 母线不同电压等级指标数据-日表 服务实现类
 * </p>
 *
 * @author xuyang
 * @since 2023-11-27
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class RDimVoltageDServiceImpl extends MppServiceImpl<RDimVoltageDMapper, RDimVoltageD> implements IRDimVoltageDService {

    private final PmsMonitorPOMapper pmsMonitorPOMapper;

    private final GeneratrixWireMapper generatrixWireMapper;

    @Override
    public void busbarVoltageD(CalculatedParam<DeptGetBusBarDTO> calculatedParam) {
        List<RDimVoltageD> result = new ArrayList<>();
        List<DeptGetBusBarDTO> deptList = calculatedParam.getIdList();
        String beginDay = LocalDateTimeUtil.format(LocalDateTimeUtil.beginOfDay(LocalDateTimeUtil.parse(calculatedParam.getDataDate(), DatePattern.NORM_DATE_PATTERN)),DatePattern.NORM_DATETIME_PATTERN);
        String endDay = LocalDateTimeUtil.format(LocalDateTimeUtil.endOfDay(LocalDateTimeUtil.parse(calculatedParam.getDataDate(), DatePattern.NORM_DATE_PATTERN)),DatePattern.NORM_DATETIME_PATTERN);
        Set<String> lineList = new HashSet<>();
        Set<String> busBarList = new HashSet<>();
        //获取监测点集合
        deptList.forEach(item->{
            lineList.addAll(item.getBusBarAndMonitorIDs());
            busBarList.addAll(item.getBusBarIds());
        });
        if (CollectionUtil.isNotEmpty(lineList)){
            //获取监测点信息
            List<Monitor> list1 = getMonitorInfo(lineList);
            //获取监测点数据
            List<LineDataDto> list2 = getLineData(beginDay,endDay,lineList);
            //获取母线信息
            List<GeneratrixWire> list3 = getBusBarInfo(busBarList);
            //循环区域信息,筛选符合条件的数据,做统计
            deptList.forEach(item->{
                List<String> list = item.getBusBarIds();
                if (CollUtil.isNotEmpty(list)) {
                    RDimVoltageD rDimVoltageD = new RDimVoltageD();
                    rDimVoltageD.setOrgId(item.getUnitId());
                    rDimVoltageD.setStatisDate(LocalDate.parse(calculatedParam.getDataDate(), DatePattern.NORM_DATE_FORMATTER));
                    //取母线并集
                    List<GeneratrixWire> list4 = list3.stream().filter(obj -> list.contains(obj.getId())).collect(Collectors.toList());
                    //根据母线电压等级分组
                    Map<String, List<GeneratrixWire>> map1 = list4.stream().collect(Collectors.groupingBy(GeneratrixWire::getScale));
                    //循环分组数据，获取母线下监测点数据
                    map1.forEach((k, v) -> {
                        RDimVoltageD dto = assignment(k,rDimVoltageD,v,list1,list2);
                        result.add(dto);
                    });
                }
            });
        }
        if (CollectionUtil.isNotEmpty(result)){
            this.saveOrUpdateBatchByMultiId(result);
        }
    }

    /**
     * 获取监测点信息
     * @param lineList 监测点集合
     * @return 监测点信息
     */
    public List<Monitor> getMonitorInfo(Set<String> lineList) {
        LambdaQueryWrapper<Monitor> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(Monitor::getId,lineList).eq(Monitor::getStatus,1);
        return pmsMonitorPOMapper.selectList(lambdaQueryWrapper);
    }

    /**
     * 获取母线信息
     * @param busBarList 监测点集合
     * @return 母线信息
     */
    public List<GeneratrixWire> getBusBarInfo(Set<String> busBarList){
        LambdaQueryWrapper<GeneratrixWire> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(GeneratrixWire::getId,busBarList).eq(GeneratrixWire::getStatus, 1);
        return generatrixWireMapper.selectList(lambdaQueryWrapper);
    }

    /**
     * 获取监测点数据
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @param lineList  监测点集合
     * @return 母线信息
     */
    public List<LineDataDto> getLineData(String startTime, String endTime, Set<String> lineList){
        return this.baseMapper.getLineData(startTime,endTime,lineList);
    }

    /**
     * 给实体赋值
     * @param rDimVoltageD  对象
     */
    public RDimVoltageD assignment(String voltage, RDimVoltageD rDimVoltageD, List<GeneratrixWire> list1, List<Monitor> list2,  List<LineDataDto> list3) {
        RDimVoltageD result = new RDimVoltageD();
        BeanUtils.copyProperties(rDimVoltageD,result);
        result.setVoltageType(voltage);
        //不同电压等级下，母线的id
        List<String> l1 = list1.stream().map(GeneratrixWire::getId).collect(Collectors.toList());
        //获取这些母线下的监测点
        List<Monitor> l2 = list2.stream().filter(obj -> l1.contains(obj.getLineId())).collect(Collectors.toList());
        //获取监测点数据
        List<LineDataDto> l3 = list3.stream().filter(vo->l2.stream().map(Monitor::getId).collect(Collectors.toList()).contains(vo.getLineId())).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(l3)){
            result.setV(l3.stream().mapToDouble(LineDataDto::getRms).average().orElse(0d));
            result.setVUnbalance(l3.stream().mapToDouble(LineDataDto::getVUnbalance).average().orElse(0d));
            result.setPst(l3.stream().mapToDouble(LineDataDto::getPst).average().orElse(0d));
            result.setVThd(l3.stream().mapToDouble(LineDataDto::getVThd).average().orElse(0d));
            result.setV1(l3.stream().mapToDouble(LineDataDto::getV1).average().orElse(0d));
            result.setV2(l3.stream().mapToDouble(LineDataDto::getV2).average().orElse(0d));
            result.setV3(l3.stream().mapToDouble(LineDataDto::getV3).average().orElse(0d));
            result.setV4(l3.stream().mapToDouble(LineDataDto::getV4).average().orElse(0d));
            result.setV5(l3.stream().mapToDouble(LineDataDto::getV5).average().orElse(0d));
            result.setV6(l3.stream().mapToDouble(LineDataDto::getV6).average().orElse(0d));
            result.setV7(l3.stream().mapToDouble(LineDataDto::getV7).average().orElse(0d));
            result.setV8(l3.stream().mapToDouble(LineDataDto::getV8).average().orElse(0d));
            result.setV9(l3.stream().mapToDouble(LineDataDto::getV9).average().orElse(0d));
            result.setV10(l3.stream().mapToDouble(LineDataDto::getV10).average().orElse(0d));
            result.setV11(l3.stream().mapToDouble(LineDataDto::getV11).average().orElse(0d));
            result.setV12(l3.stream().mapToDouble(LineDataDto::getV12).average().orElse(0d));
            result.setV13(l3.stream().mapToDouble(LineDataDto::getV13).average().orElse(0d));
            result.setV14(l3.stream().mapToDouble(LineDataDto::getV14).average().orElse(0d));
            result.setV15(l3.stream().mapToDouble(LineDataDto::getV15).average().orElse(0d));
            result.setV16(l3.stream().mapToDouble(LineDataDto::getV16).average().orElse(0d));
            result.setV17(l3.stream().mapToDouble(LineDataDto::getV17).average().orElse(0d));
            result.setV18(l3.stream().mapToDouble(LineDataDto::getV18).average().orElse(0d));
            result.setV19(l3.stream().mapToDouble(LineDataDto::getV19).average().orElse(0d));
            result.setV20(l3.stream().mapToDouble(LineDataDto::getV20).average().orElse(0d));
            result.setV21(l3.stream().mapToDouble(LineDataDto::getV21).average().orElse(0d));
            result.setV22(l3.stream().mapToDouble(LineDataDto::getV22).average().orElse(0d));
            result.setV23(l3.stream().mapToDouble(LineDataDto::getV23).average().orElse(0d));
            result.setV24(l3.stream().mapToDouble(LineDataDto::getV24).average().orElse(0d));
            result.setV25(l3.stream().mapToDouble(LineDataDto::getV25).average().orElse(0d));
            result.setV26(l3.stream().mapToDouble(LineDataDto::getV26).average().orElse(0d));
            result.setV27(l3.stream().mapToDouble(LineDataDto::getV27).average().orElse(0d));
            result.setV28(l3.stream().mapToDouble(LineDataDto::getV28).average().orElse(0d));
            result.setV29(l3.stream().mapToDouble(LineDataDto::getV29).average().orElse(0d));
            result.setV30(l3.stream().mapToDouble(LineDataDto::getV30).average().orElse(0d));
            result.setV31(l3.stream().mapToDouble(LineDataDto::getV31).average().orElse(0d));
            result.setV32(l3.stream().mapToDouble(LineDataDto::getV32).average().orElse(0d));
            result.setV33(l3.stream().mapToDouble(LineDataDto::getV33).average().orElse(0d));
            result.setV34(l3.stream().mapToDouble(LineDataDto::getV34).average().orElse(0d));
            result.setV35(l3.stream().mapToDouble(LineDataDto::getV35).average().orElse(0d));
            result.setV36(l3.stream().mapToDouble(LineDataDto::getV36).average().orElse(0d));
            result.setV37(l3.stream().mapToDouble(LineDataDto::getV37).average().orElse(0d));
            result.setV38(l3.stream().mapToDouble(LineDataDto::getV38).average().orElse(0d));
            result.setV39(l3.stream().mapToDouble(LineDataDto::getV39).average().orElse(0d));
            result.setV40(l3.stream().mapToDouble(LineDataDto::getV40).average().orElse(0d));
            result.setV41(l3.stream().mapToDouble(LineDataDto::getV41).average().orElse(0d));
            result.setV42(l3.stream().mapToDouble(LineDataDto::getV42).average().orElse(0d));
            result.setV43(l3.stream().mapToDouble(LineDataDto::getV43).average().orElse(0d));
            result.setV44(l3.stream().mapToDouble(LineDataDto::getV44).average().orElse(0d));
            result.setV45(l3.stream().mapToDouble(LineDataDto::getV45).average().orElse(0d));
            result.setV46(l3.stream().mapToDouble(LineDataDto::getV46).average().orElse(0d));
            result.setV47(l3.stream().mapToDouble(LineDataDto::getV47).average().orElse(0d));
            result.setV48(l3.stream().mapToDouble(LineDataDto::getV48).average().orElse(0d));
            result.setV49(l3.stream().mapToDouble(LineDataDto::getV49).average().orElse(0d));
            result.setV50(l3.stream().mapToDouble(LineDataDto::getV50).average().orElse(0d));
            result.setINeg(l3.stream().mapToDouble(LineDataDto::getINeg).average().orElse(0d));
        }
        return result;
    }

}
