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

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
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.harmonic.pojo.po.dim.RDimVoltageD;
import com.njcn.harmonic.pojo.po.dim.RDimVoltageM;
import com.njcn.prepare.harmonic.mapper.mysql.dim.RDimVoltageDMapper;
import com.njcn.prepare.harmonic.mapper.mysql.dim.RDimVoltageMMapper;
import com.njcn.prepare.harmonic.pojo.bo.CalculatedParam;
import com.njcn.prepare.harmonic.service.mysql.dim.IRDimVoltageMService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

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

/**
 * <p>
 * 区域母线**电压等级**指标标准差、平均值-月表 服务实现类
 * </p>
 *
 * @author xuyang
 * @since 2023-11-29
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class RDimVoltageMServiceImpl extends MppServiceImpl<RDimVoltageMMapper, RDimVoltageM> implements IRDimVoltageMService {

    private final RDimVoltageDMapper rDimVoltageDMapper;

    @Override
    public void busbarVoltageM(CalculatedParam<DeptGetBusBarDTO> calculatedParam) {
        List<RDimVoltageM> result = new ArrayList<>();
        List<DeptGetBusBarDTO> list = calculatedParam.getIdList();
        DateTime startTime = DateUtil.beginOfMonth(DateUtil.parse(calculatedParam.getDataDate()));
        DateTime endTime = DateUtil.endOfMonth(DateUtil.parse(calculatedParam.getDataDate()));
        LocalDate time = LocalDateTimeUtil.parseDate(startTime.toString(DatePattern.NORM_DATE_PATTERN),DatePattern.NORM_DATE_FORMATTER);
        List<String> deptList = list.stream().map(DeptGetBusBarDTO::getUnitId).collect(Collectors.toList());
        //获取日表数据
        Map<String, List<RDimVoltageD>> map = getDayData(startTime,endTime,deptList);
        map.forEach((k,v)->{
            Map<String, List<RDimVoltageD>> map1 = v.stream().collect(Collectors.groupingBy(RDimVoltageD::getVoltageType));
            map1.forEach((k1,v1)->{
                //获取平均值
                RDimVoltageM rDimVoltageM1 = getAvg(v1,k,time,k1);
                result.add(rDimVoltageM1);
                //获取标准差
                RDimVoltageM rDimVoltageM2 = getSd(v1,k,time,k1,rDimVoltageM1);
                result.add(rDimVoltageM2);
            });
        });
        if (CollectionUtil.isNotEmpty(result)){
            this.saveOrUpdateBatchByMultiId(result);
        }
    }

    /**
     * 获取日表数据，按照单位分组
     * @param startTime 起始时间
     * @param endTime   结束时间
     * @param deptList  单位集合
     * @return
     */
    public Map<String, List<RDimVoltageD>> getDayData(DateTime startTime, DateTime endTime, List<String> deptList) {
        LambdaQueryWrapper<RDimVoltageD> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(RDimVoltageD::getOrgId,deptList).between(RDimVoltageD::getStatisDate,startTime,endTime);
        List<RDimVoltageD> list = rDimVoltageDMapper.selectList(lambdaQueryWrapper);
        return list.stream().collect(Collectors.groupingBy(RDimVoltageD::getOrgId));
    }

    /**
     * 获取平均值
     * @param list          数据集合
     */
    public RDimVoltageM getAvg(List<RDimVoltageD> list, String orgId, LocalDate time, String voltageLevel) {
        RDimVoltageM rDimVoltageM = new RDimVoltageM();
        rDimVoltageM.setOrgId(orgId);
        rDimVoltageM.setStatisDate(time);
        rDimVoltageM.setVoltageType(voltageLevel);
        rDimVoltageM.setDataType("avg");
        rDimVoltageM.setV(list.stream().mapToDouble(RDimVoltageD::getV).average().orElse(0d));
        rDimVoltageM.setVUnbalance(list.stream().mapToDouble(RDimVoltageD::getVUnbalance).average().orElse(0d));
        rDimVoltageM.setPst(list.stream().mapToDouble(RDimVoltageD::getPst).average().orElse(0d));
        rDimVoltageM.setVThd(list.stream().mapToDouble(RDimVoltageD::getVThd).average().orElse(0d));
        rDimVoltageM.setV1(list.stream().mapToDouble(RDimVoltageD::getV1).average().orElse(0d));
        rDimVoltageM.setV2(list.stream().mapToDouble(RDimVoltageD::getV2).average().orElse(0d));
        rDimVoltageM.setV3(list.stream().mapToDouble(RDimVoltageD::getV3).average().orElse(0d));
        rDimVoltageM.setV4(list.stream().mapToDouble(RDimVoltageD::getV4).average().orElse(0d));
        rDimVoltageM.setV5(list.stream().mapToDouble(RDimVoltageD::getV5).average().orElse(0d));
        rDimVoltageM.setV6(list.stream().mapToDouble(RDimVoltageD::getV6).average().orElse(0d));
        rDimVoltageM.setV7(list.stream().mapToDouble(RDimVoltageD::getV7).average().orElse(0d));
        rDimVoltageM.setV8(list.stream().mapToDouble(RDimVoltageD::getV8).average().orElse(0d));
        rDimVoltageM.setV9(list.stream().mapToDouble(RDimVoltageD::getV9).average().orElse(0d));
        rDimVoltageM.setV10(list.stream().mapToDouble(RDimVoltageD::getV10).average().orElse(0d));
        rDimVoltageM.setV11(list.stream().mapToDouble(RDimVoltageD::getV11).average().orElse(0d));
        rDimVoltageM.setV12(list.stream().mapToDouble(RDimVoltageD::getV12).average().orElse(0d));
        rDimVoltageM.setV13(list.stream().mapToDouble(RDimVoltageD::getV13).average().orElse(0d));
        rDimVoltageM.setV14(list.stream().mapToDouble(RDimVoltageD::getV14).average().orElse(0d));
        rDimVoltageM.setV15(list.stream().mapToDouble(RDimVoltageD::getV15).average().orElse(0d));
        rDimVoltageM.setV16(list.stream().mapToDouble(RDimVoltageD::getV16).average().orElse(0d));
        rDimVoltageM.setV17(list.stream().mapToDouble(RDimVoltageD::getV17).average().orElse(0d));
        rDimVoltageM.setV18(list.stream().mapToDouble(RDimVoltageD::getV18).average().orElse(0d));
        rDimVoltageM.setV19(list.stream().mapToDouble(RDimVoltageD::getV19).average().orElse(0d));
        rDimVoltageM.setV20(list.stream().mapToDouble(RDimVoltageD::getV20).average().orElse(0d));
        rDimVoltageM.setV21(list.stream().mapToDouble(RDimVoltageD::getV21).average().orElse(0d));
        rDimVoltageM.setV22(list.stream().mapToDouble(RDimVoltageD::getV22).average().orElse(0d));
        rDimVoltageM.setV23(list.stream().mapToDouble(RDimVoltageD::getV23).average().orElse(0d));
        rDimVoltageM.setV24(list.stream().mapToDouble(RDimVoltageD::getV24).average().orElse(0d));
        rDimVoltageM.setV25(list.stream().mapToDouble(RDimVoltageD::getV25).average().orElse(0d));
        rDimVoltageM.setV26(list.stream().mapToDouble(RDimVoltageD::getV26).average().orElse(0d));
        rDimVoltageM.setV27(list.stream().mapToDouble(RDimVoltageD::getV27).average().orElse(0d));
        rDimVoltageM.setV28(list.stream().mapToDouble(RDimVoltageD::getV28).average().orElse(0d));
        rDimVoltageM.setV29(list.stream().mapToDouble(RDimVoltageD::getV29).average().orElse(0d));
        rDimVoltageM.setV30(list.stream().mapToDouble(RDimVoltageD::getV30).average().orElse(0d));
        rDimVoltageM.setV31(list.stream().mapToDouble(RDimVoltageD::getV31).average().orElse(0d));
        rDimVoltageM.setV32(list.stream().mapToDouble(RDimVoltageD::getV32).average().orElse(0d));
        rDimVoltageM.setV33(list.stream().mapToDouble(RDimVoltageD::getV33).average().orElse(0d));
        rDimVoltageM.setV34(list.stream().mapToDouble(RDimVoltageD::getV34).average().orElse(0d));
        rDimVoltageM.setV35(list.stream().mapToDouble(RDimVoltageD::getV35).average().orElse(0d));
        rDimVoltageM.setV36(list.stream().mapToDouble(RDimVoltageD::getV36).average().orElse(0d));
        rDimVoltageM.setV37(list.stream().mapToDouble(RDimVoltageD::getV37).average().orElse(0d));
        rDimVoltageM.setV38(list.stream().mapToDouble(RDimVoltageD::getV38).average().orElse(0d));
        rDimVoltageM.setV39(list.stream().mapToDouble(RDimVoltageD::getV39).average().orElse(0d));
        rDimVoltageM.setV40(list.stream().mapToDouble(RDimVoltageD::getV40).average().orElse(0d));
        rDimVoltageM.setV41(list.stream().mapToDouble(RDimVoltageD::getV41).average().orElse(0d));
        rDimVoltageM.setV42(list.stream().mapToDouble(RDimVoltageD::getV42).average().orElse(0d));
        rDimVoltageM.setV43(list.stream().mapToDouble(RDimVoltageD::getV43).average().orElse(0d));
        rDimVoltageM.setV44(list.stream().mapToDouble(RDimVoltageD::getV44).average().orElse(0d));
        rDimVoltageM.setV45(list.stream().mapToDouble(RDimVoltageD::getV45).average().orElse(0d));
        rDimVoltageM.setV46(list.stream().mapToDouble(RDimVoltageD::getV46).average().orElse(0d));
        rDimVoltageM.setV47(list.stream().mapToDouble(RDimVoltageD::getV47).average().orElse(0d));
        rDimVoltageM.setV48(list.stream().mapToDouble(RDimVoltageD::getV48).average().orElse(0d));
        rDimVoltageM.setV49(list.stream().mapToDouble(RDimVoltageD::getV49).average().orElse(0d));
        rDimVoltageM.setV50(list.stream().mapToDouble(RDimVoltageD::getV50).average().orElse(0d));
        rDimVoltageM.setINeg(list.stream().mapToDouble(RDimVoltageD::getINeg).average().orElse(0d));
        return rDimVoltageM;
    }

    /**
     * 获取标准差
     * @param list          数据集合
     */
    public RDimVoltageM getSd(List<RDimVoltageD> list, String orgId, LocalDate time, String voltageLevel,RDimVoltageM rDimVoltageM) {
        double limit = 3.1415926;
        RDimVoltageM rDimVoltageM1 = new RDimVoltageM();
        rDimVoltageM1.setOrgId(orgId);
        rDimVoltageM1.setStatisDate(time);
        rDimVoltageM1.setVoltageType(voltageLevel);
        rDimVoltageM1.setDataType("sd");
        rDimVoltageM1.setV(rDimVoltageM.getV() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV).collect(Collectors.toList()),rDimVoltageM.getV()));
        rDimVoltageM1.setVUnbalance(rDimVoltageM.getVUnbalance() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getVUnbalance).collect(Collectors.toList()),rDimVoltageM.getVUnbalance()));
        rDimVoltageM1.setVThd(rDimVoltageM.getVThd() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getVThd).collect(Collectors.toList()),rDimVoltageM.getVThd()));
        rDimVoltageM1.setPst(rDimVoltageM.getPst() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getPst).collect(Collectors.toList()),rDimVoltageM.getPst()));
        rDimVoltageM1.setV1(rDimVoltageM.getV1() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV1).collect(Collectors.toList()),rDimVoltageM.getV1()));
        rDimVoltageM1.setV2(rDimVoltageM.getV2() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV2).collect(Collectors.toList()),rDimVoltageM.getV2()));
        rDimVoltageM1.setV3(rDimVoltageM.getV3() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV3).collect(Collectors.toList()),rDimVoltageM.getV3()));
        rDimVoltageM1.setV4(rDimVoltageM.getV4() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV4).collect(Collectors.toList()),rDimVoltageM.getV4()));
        rDimVoltageM1.setV5(rDimVoltageM.getV5() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV5).collect(Collectors.toList()),rDimVoltageM.getV5()));
        rDimVoltageM1.setV6(rDimVoltageM.getV6() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV6).collect(Collectors.toList()),rDimVoltageM.getV6()));
        rDimVoltageM1.setV7(rDimVoltageM.getV7() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV7).collect(Collectors.toList()),rDimVoltageM.getV7()));
        rDimVoltageM1.setV8(rDimVoltageM.getV8() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV8).collect(Collectors.toList()),rDimVoltageM.getV8()));
        rDimVoltageM1.setV9(rDimVoltageM.getV9() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV9).collect(Collectors.toList()),rDimVoltageM.getV9()));
        rDimVoltageM1.setV10(rDimVoltageM.getV10() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV10).collect(Collectors.toList()),rDimVoltageM.getV10()));
        rDimVoltageM1.setV11(rDimVoltageM.getV11() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV11).collect(Collectors.toList()),rDimVoltageM.getV11()));
        rDimVoltageM1.setV12(rDimVoltageM.getV12() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV12).collect(Collectors.toList()),rDimVoltageM.getV12()));
        rDimVoltageM1.setV13(rDimVoltageM.getV13() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV13).collect(Collectors.toList()),rDimVoltageM.getV13()));
        rDimVoltageM1.setV14(rDimVoltageM.getV14() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV14).collect(Collectors.toList()),rDimVoltageM.getV14()));
        rDimVoltageM1.setV15(rDimVoltageM.getV15() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV15).collect(Collectors.toList()),rDimVoltageM.getV15()));
        rDimVoltageM1.setV16(rDimVoltageM.getV16() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV16).collect(Collectors.toList()),rDimVoltageM.getV16()));
        rDimVoltageM1.setV17(rDimVoltageM.getV17() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV17).collect(Collectors.toList()),rDimVoltageM.getV17()));
        rDimVoltageM1.setV18(rDimVoltageM.getV18() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV18).collect(Collectors.toList()),rDimVoltageM.getV18()));
        rDimVoltageM1.setV19(rDimVoltageM.getV19() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV19).collect(Collectors.toList()),rDimVoltageM.getV19()));
        rDimVoltageM1.setV20(rDimVoltageM.getV20() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV20).collect(Collectors.toList()),rDimVoltageM.getV20()));
        rDimVoltageM1.setV21(rDimVoltageM.getV21() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV21).collect(Collectors.toList()),rDimVoltageM.getV21()));
        rDimVoltageM1.setV22(rDimVoltageM.getV22() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV22).collect(Collectors.toList()),rDimVoltageM.getV22()));
        rDimVoltageM1.setV23(rDimVoltageM.getV23() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV23).collect(Collectors.toList()),rDimVoltageM.getV23()));
        rDimVoltageM1.setV24(rDimVoltageM.getV24() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV24).collect(Collectors.toList()),rDimVoltageM.getV24()));
        rDimVoltageM1.setV25(rDimVoltageM.getV25() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV25).collect(Collectors.toList()),rDimVoltageM.getV25()));
        rDimVoltageM1.setV26(rDimVoltageM.getV26() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV26).collect(Collectors.toList()),rDimVoltageM.getV26()));
        rDimVoltageM1.setV27(rDimVoltageM.getV27() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV27).collect(Collectors.toList()),rDimVoltageM.getV27()));
        rDimVoltageM1.setV28(rDimVoltageM.getV28() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV28).collect(Collectors.toList()),rDimVoltageM.getV28()));
        rDimVoltageM1.setV29(rDimVoltageM.getV29() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV29).collect(Collectors.toList()),rDimVoltageM.getV29()));
        rDimVoltageM1.setV30(rDimVoltageM.getV30() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV30).collect(Collectors.toList()),rDimVoltageM.getV30()));
        rDimVoltageM1.setV31(rDimVoltageM.getV31() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV31).collect(Collectors.toList()),rDimVoltageM.getV31()));
        rDimVoltageM1.setV32(rDimVoltageM.getV32() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV32).collect(Collectors.toList()),rDimVoltageM.getV32()));
        rDimVoltageM1.setV33(rDimVoltageM.getV33() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV33).collect(Collectors.toList()),rDimVoltageM.getV33()));
        rDimVoltageM1.setV34(rDimVoltageM.getV34() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV34).collect(Collectors.toList()),rDimVoltageM.getV34()));
        rDimVoltageM1.setV35(rDimVoltageM.getV35() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV35).collect(Collectors.toList()),rDimVoltageM.getV35()));
        rDimVoltageM1.setV36(rDimVoltageM.getV36() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV36).collect(Collectors.toList()),rDimVoltageM.getV36()));
        rDimVoltageM1.setV37(rDimVoltageM.getV37() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV37).collect(Collectors.toList()),rDimVoltageM.getV37()));
        rDimVoltageM1.setV38(rDimVoltageM.getV38() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV38).collect(Collectors.toList()),rDimVoltageM.getV38()));
        rDimVoltageM1.setV39(rDimVoltageM.getV39() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV39).collect(Collectors.toList()),rDimVoltageM.getV39()));
        rDimVoltageM1.setV40(rDimVoltageM.getV40() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV40).collect(Collectors.toList()),rDimVoltageM.getV40()));
        rDimVoltageM1.setV41(rDimVoltageM.getV41() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV41).collect(Collectors.toList()),rDimVoltageM.getV41()));
        rDimVoltageM1.setV42(rDimVoltageM.getV42() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV42).collect(Collectors.toList()),rDimVoltageM.getV42()));
        rDimVoltageM1.setV43(rDimVoltageM.getV43() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV43).collect(Collectors.toList()),rDimVoltageM.getV43()));
        rDimVoltageM1.setV44(rDimVoltageM.getV44() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV44).collect(Collectors.toList()),rDimVoltageM.getV44()));
        rDimVoltageM1.setV45(rDimVoltageM.getV45() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV45).collect(Collectors.toList()),rDimVoltageM.getV45()));
        rDimVoltageM1.setV46(rDimVoltageM.getV46() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV46).collect(Collectors.toList()),rDimVoltageM.getV46()));
        rDimVoltageM1.setV47(rDimVoltageM.getV47() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV47).collect(Collectors.toList()),rDimVoltageM.getV47()));
        rDimVoltageM1.setV48(rDimVoltageM.getV48() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV48).collect(Collectors.toList()),rDimVoltageM.getV48()));
        rDimVoltageM1.setV49(rDimVoltageM.getV49() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV49).collect(Collectors.toList()),rDimVoltageM.getV49()));
        rDimVoltageM1.setV50(rDimVoltageM.getV50() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getV50).collect(Collectors.toList()),rDimVoltageM.getV50()));
        rDimVoltageM1.setINeg(rDimVoltageM.getINeg() == limit ? limit : calculateStandardDeviation(list.stream().map(RDimVoltageD::getINeg).collect(Collectors.toList()),rDimVoltageM.getINeg()));
        return rDimVoltageM1;
    }

    private static double calculateStandardDeviation(List<Double> data, double mean) {
        return Math.sqrt(calculateVariance(data, mean));
    }

    private static double calculateVariance(List<Double> data, double mean) {
        return data.stream()
                .mapToDouble(Double::doubleValue)
                .map(value -> Math.pow(value - mean, 2))
                .average()
                .orElse(0.0);
    }

}
