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.RDimVoltageY;
import com.njcn.prepare.harmonic.mapper.mysql.dim.RDimVoltageDMapper;
import com.njcn.prepare.harmonic.mapper.mysql.dim.RDimVoltageYMapper;
import com.njcn.prepare.harmonic.pojo.bo.CalculatedParam;
import com.njcn.prepare.harmonic.service.mysql.dim.IRDimVoltageYService;
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 RDimVoltageYServiceImpl extends MppServiceImpl<RDimVoltageYMapper, RDimVoltageY> implements IRDimVoltageYService {
    private final RDimVoltageDMapper rDimVoltageDMapper;

    @Override
    public void busbarVoltageY(CalculatedParam<DeptGetBusBarDTO> calculatedParam) {
        List<RDimVoltageY> result = new ArrayList<>();
        List<DeptGetBusBarDTO> list = calculatedParam.getIdList();
        DateTime startTime = DateUtil.beginOfYear(DateUtil.parse(calculatedParam.getDataDate()));
        DateTime endTime = DateUtil.endOfYear(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)->{
                //获取平均值
                RDimVoltageY rDimVoltageY1 = getAvg(v1,k,time,k1);
                result.add(rDimVoltageY1);
                //获取标准差
                RDimVoltageY rDimVoltageY2 = getSd(v1,k,time,k1,rDimVoltageY1);
                result.add(rDimVoltageY2);
            });
        });
        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 RDimVoltageY getAvg(List<RDimVoltageD> list, String orgId, LocalDate time, String voltageLevel) {
        RDimVoltageY rDimVoltageY = new RDimVoltageY();
        rDimVoltageY.setOrgId(orgId);
        rDimVoltageY.setStatisDate(time);
        rDimVoltageY.setVoltageType(voltageLevel);
        rDimVoltageY.setDataType("avg");
        rDimVoltageY.setV(list.stream().mapToDouble(RDimVoltageD::getV).average().orElse(0d));
        rDimVoltageY.setVUnbalance(list.stream().mapToDouble(RDimVoltageD::getVUnbalance).average().orElse(0d));
        rDimVoltageY.setPst(list.stream().mapToDouble(RDimVoltageD::getPst).average().orElse(0d));
        rDimVoltageY.setVThd(list.stream().mapToDouble(RDimVoltageD::getVThd).average().orElse(0d));
        rDimVoltageY.setV1(list.stream().mapToDouble(RDimVoltageD::getV1).average().orElse(0d));
        rDimVoltageY.setV2(list.stream().mapToDouble(RDimVoltageD::getV2).average().orElse(0d));
        rDimVoltageY.setV3(list.stream().mapToDouble(RDimVoltageD::getV3).average().orElse(0d));
        rDimVoltageY.setV4(list.stream().mapToDouble(RDimVoltageD::getV4).average().orElse(0d));
        rDimVoltageY.setV5(list.stream().mapToDouble(RDimVoltageD::getV5).average().orElse(0d));
        rDimVoltageY.setV6(list.stream().mapToDouble(RDimVoltageD::getV6).average().orElse(0d));
        rDimVoltageY.setV7(list.stream().mapToDouble(RDimVoltageD::getV7).average().orElse(0d));
        rDimVoltageY.setV8(list.stream().mapToDouble(RDimVoltageD::getV8).average().orElse(0d));
        rDimVoltageY.setV9(list.stream().mapToDouble(RDimVoltageD::getV9).average().orElse(0d));
        rDimVoltageY.setV10(list.stream().mapToDouble(RDimVoltageD::getV10).average().orElse(0d));
        rDimVoltageY.setV11(list.stream().mapToDouble(RDimVoltageD::getV11).average().orElse(0d));
        rDimVoltageY.setV12(list.stream().mapToDouble(RDimVoltageD::getV12).average().orElse(0d));
        rDimVoltageY.setV13(list.stream().mapToDouble(RDimVoltageD::getV13).average().orElse(0d));
        rDimVoltageY.setV14(list.stream().mapToDouble(RDimVoltageD::getV14).average().orElse(0d));
        rDimVoltageY.setV15(list.stream().mapToDouble(RDimVoltageD::getV15).average().orElse(0d));
        rDimVoltageY.setV16(list.stream().mapToDouble(RDimVoltageD::getV16).average().orElse(0d));
        rDimVoltageY.setV17(list.stream().mapToDouble(RDimVoltageD::getV17).average().orElse(0d));
        rDimVoltageY.setV18(list.stream().mapToDouble(RDimVoltageD::getV18).average().orElse(0d));
        rDimVoltageY.setV19(list.stream().mapToDouble(RDimVoltageD::getV19).average().orElse(0d));
        rDimVoltageY.setV20(list.stream().mapToDouble(RDimVoltageD::getV20).average().orElse(0d));
        rDimVoltageY.setV21(list.stream().mapToDouble(RDimVoltageD::getV21).average().orElse(0d));
        rDimVoltageY.setV22(list.stream().mapToDouble(RDimVoltageD::getV22).average().orElse(0d));
        rDimVoltageY.setV23(list.stream().mapToDouble(RDimVoltageD::getV23).average().orElse(0d));
        rDimVoltageY.setV24(list.stream().mapToDouble(RDimVoltageD::getV24).average().orElse(0d));
        rDimVoltageY.setV25(list.stream().mapToDouble(RDimVoltageD::getV25).average().orElse(0d));
        rDimVoltageY.setV26(list.stream().mapToDouble(RDimVoltageD::getV26).average().orElse(0d));
        rDimVoltageY.setV27(list.stream().mapToDouble(RDimVoltageD::getV27).average().orElse(0d));
        rDimVoltageY.setV28(list.stream().mapToDouble(RDimVoltageD::getV28).average().orElse(0d));
        rDimVoltageY.setV29(list.stream().mapToDouble(RDimVoltageD::getV29).average().orElse(0d));
        rDimVoltageY.setV30(list.stream().mapToDouble(RDimVoltageD::getV30).average().orElse(0d));
        rDimVoltageY.setV31(list.stream().mapToDouble(RDimVoltageD::getV31).average().orElse(0d));
        rDimVoltageY.setV32(list.stream().mapToDouble(RDimVoltageD::getV32).average().orElse(0d));
        rDimVoltageY.setV33(list.stream().mapToDouble(RDimVoltageD::getV33).average().orElse(0d));
        rDimVoltageY.setV34(list.stream().mapToDouble(RDimVoltageD::getV34).average().orElse(0d));
        rDimVoltageY.setV35(list.stream().mapToDouble(RDimVoltageD::getV35).average().orElse(0d));
        rDimVoltageY.setV36(list.stream().mapToDouble(RDimVoltageD::getV36).average().orElse(0d));
        rDimVoltageY.setV37(list.stream().mapToDouble(RDimVoltageD::getV37).average().orElse(0d));
        rDimVoltageY.setV38(list.stream().mapToDouble(RDimVoltageD::getV38).average().orElse(0d));
        rDimVoltageY.setV39(list.stream().mapToDouble(RDimVoltageD::getV39).average().orElse(0d));
        rDimVoltageY.setV40(list.stream().mapToDouble(RDimVoltageD::getV40).average().orElse(0d));
        rDimVoltageY.setV41(list.stream().mapToDouble(RDimVoltageD::getV41).average().orElse(0d));
        rDimVoltageY.setV42(list.stream().mapToDouble(RDimVoltageD::getV42).average().orElse(0d));
        rDimVoltageY.setV43(list.stream().mapToDouble(RDimVoltageD::getV43).average().orElse(0d));
        rDimVoltageY.setV44(list.stream().mapToDouble(RDimVoltageD::getV44).average().orElse(0d));
        rDimVoltageY.setV45(list.stream().mapToDouble(RDimVoltageD::getV45).average().orElse(0d));
        rDimVoltageY.setV46(list.stream().mapToDouble(RDimVoltageD::getV46).average().orElse(0d));
        rDimVoltageY.setV47(list.stream().mapToDouble(RDimVoltageD::getV47).average().orElse(0d));
        rDimVoltageY.setV48(list.stream().mapToDouble(RDimVoltageD::getV48).average().orElse(0d));
        rDimVoltageY.setV49(list.stream().mapToDouble(RDimVoltageD::getV49).average().orElse(0d));
        rDimVoltageY.setV50(list.stream().mapToDouble(RDimVoltageD::getV50).average().orElse(0d));
        rDimVoltageY.setINeg(list.stream().mapToDouble(RDimVoltageD::getINeg).average().orElse(0d));
        return rDimVoltageY;
    }

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

    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);
    }


}
