package com.njcn.product.advance.harmonicUp.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.*;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.influx.imapper.DataIMapper;
import com.njcn.influx.imapper.DataVMapper;
import com.njcn.influx.pojo.constant.InfluxDBTableConstant;
import com.njcn.influx.pojo.po.DataI;
import com.njcn.influx.pojo.po.DataV;
import com.njcn.influx.query.InfluxQueryWrapper;
import com.njcn.product.advance.harmonicUp.imapper.DataIUpToMapper;
import com.njcn.product.advance.harmonicUp.imapper.DataVUpToMapper;
import com.njcn.product.advance.harmonicUp.mapper.UpHarmonicDetailMapper;
import com.njcn.product.advance.harmonicUp.pojo.po.DataIUp;
import com.njcn.product.advance.harmonicUp.pojo.po.DataVUp;
import com.njcn.product.advance.harmonicUp.pojo.po.UpHarmonicDetail;
import com.njcn.product.advance.harmonicUp.pojo.vo.UpTableInfo;
import com.njcn.product.advance.harmonicUp.service.HarmonicUpService;
import com.njcn.product.terminal.mysqlTerminal.mapper.LedgerScaleMapper;
import com.njcn.product.terminal.mysqlTerminal.pojo.dto.LedgerBaseInfo;
import com.njcn.product.terminal.mysqlTerminal.pojo.param.LargeScreenCountParam;
import com.njcn.product.terminal.mysqlTerminal.service.CommGeneralService;
import com.njcn.web.factory.PageFactory;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Author: cdf
 * @CreateTime: 2025-09-11
 * @Description:
 */
/**
 * @Author: cdf
 * @CreateTime: 2025-09-11
 * @Description: 谐波分析服务实现类，仅使用up_harmonic_detail表存储事件信息
 */
@Service
@EnableScheduling
@RequiredArgsConstructor
@Slf4j
public class HarmonicUpServiceImpl extends ServiceImpl<UpHarmonicDetailMapper,UpHarmonicDetail> implements HarmonicUpService {

    private final DataVMapper dataVMapper;
    private final DataIMapper dataIMapper;
    private final DataVUpToMapper dataVUpToMapper;
    private final DataIUpToMapper dataIUpToMapper;
    private final CommGeneralService commGeneralService;
    private final LedgerScaleMapper ledgerScaleMapper;

    // 常量定义
    final String DAY_FORMAT = DatePattern.NORM_DATE_PATTERN;
    final String MONTH_FORMAT = DatePattern.NORM_MONTH_PATTERN;

    // 配置参数
    @Value("${harmonic.voltage.change.rate.threshold:0.20}")
    private Double voltageChangeRateThreshold;

    //电流
    @Value("${harmonic.current.change.rate.threshold:0.10}")
    private Double currentChangeRateThreshold;

    @Value("${harmonic.continuous.anomaly.count:10}")
    private Integer continuousAnomalyCount;

    // 需要分析的特定谐波次数，可根据需求扩展
    private List<Integer> specificHarmonicOrders = Arrays.asList(3, 5, 7, 11, 13);

    /**
     * 每日凌晨2点执行谐波分析（分析前一天的数据）
     */
    @Scheduled(cron = "0 0 2 * * ?")
    public void dailyHarmonicAnalysis() {
        analyzePreData("");
    }

    @Override
    public void analyzePreData(String date) {
        log.info("开始执行谐波分析，日期: {}", date);

        Map<String,Map<String, Double>> avgVMap = new HashMap<>();
        Map<String,Map<String, Double>> avgIMap = new HashMap<>();

        // 计算并保存电压和电流变化率数据
        List<DataVUp> dataVUpList = calculateAndSaveDataVUp(date,avgVMap);
        List<DataIUp> dataIUpList = calculateAndSaveDataIUp(date,avgIMap);

        // 分析谐波放大事件并直接保存到up_harmonic_detail表
        analyzeAndSaveHarmonicEvents(dataVUpList, dataIUpList,avgVMap,avgIMap);

        log.info("谐波分析执行完成，日期: {}", date);
    }

    @Override
    public Page<UpHarmonicDetail> getDetail(LargeScreenCountParam param) {
        Page<UpHarmonicDetail> resultPage = new Page<>(PageFactory.getPageNum(param),PageFactory.getPageSize(param));
        DateTime date;

        LambdaQueryWrapper<UpHarmonicDetail> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        try {
            date = DateUtil.parse(param.getSearchBeginTime(),DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN));
            lambdaQueryWrapper.between(UpHarmonicDetail::getStartTime,DateUtil.beginOfDay(date),DateUtil.endOfDay(date));

        }catch (Exception e){
            date = DateUtil.parse(param.getSearchBeginTime(),DateTimeFormatter.ofPattern(DatePattern.NORM_MONTH_PATTERN));
            lambdaQueryWrapper.between(UpHarmonicDetail::getStartTime,DateUtil.beginOfMonth(date),DateUtil.endOfMonth(date));
        }
        lambdaQueryWrapper.eq(UpHarmonicDetail::getMonitorId,param.getLineId()).orderByAsc(UpHarmonicDetail::getHarmonicCount,UpHarmonicDetail::getPhase,UpHarmonicDetail::getStartTime);
        Page<UpHarmonicDetail> result = this.page(new Page<>(PageFactory.getPageNum(param),PageFactory.getPageSize(param)),lambdaQueryWrapper);
        if(CollUtil.isEmpty(result.getRecords())){
            return resultPage;
        }
        List<LedgerBaseInfo> ledgerBaseInfoList = ledgerScaleMapper.getLedgerBaseInfo(Stream.of(param.getLineId()).collect(Collectors.toList()));
        if(CollUtil.isEmpty(ledgerBaseInfoList)){
            throw new BusinessException(CommonResponseEnum.FAIL,"查询台账为空");
        }
        LedgerBaseInfo ledgerBaseInfo = ledgerBaseInfoList.get(0);
        result.getRecords().forEach(it->{
            it.setMonitorName(ledgerBaseInfo.getLineName());
            it.setStationName(ledgerBaseInfo.getStationName());
            it.setObjName(ledgerBaseInfo.getObjName());
            it.setVAvgValue(BigDecimal.valueOf(it.getVAvgValue()*1000).setScale(2,RoundingMode.HALF_UP).doubleValue());

        });
        return result;
    }

    @Override
    public Page<UpHarmonicDetail> getInfoList(LargeScreenCountParam param) {
        Page<UpHarmonicDetail> result = new Page<>(PageFactory.getPageNum(param),PageFactory.getPageSize(param));

        DateTime start = DateUtil.beginOfDay(DateUtil.parse(param.getSearchBeginTime()));
        DateTime end = DateUtil.endOfDay(DateUtil.parse(param.getSearchEndTime()));
        List<String> lineIds = commGeneralService.getRunLineIdsByDept(param.getDeptId());
        if(CollUtil.isEmpty(lineIds)){
            return result;
        }
        LambdaQueryWrapper<UpHarmonicDetail> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.between(UpHarmonicDetail::getStartTime,start,end)
                .in(UpHarmonicDetail::getMonitorId,lineIds).orderByDesc(UpHarmonicDetail::getStartTime);
        result = this.page(new Page<>(PageFactory.getPageNum(param),PageFactory.getPageSize(param)),lambdaQueryWrapper);
        if(CollUtil.isEmpty(result.getRecords())){
            return result;
        }
        List<String> ids = result.getRecords().stream().map(UpHarmonicDetail::getMonitorId).distinct().collect(Collectors.toList());
        List<LedgerBaseInfo> ledgerBaseInfoList = ledgerScaleMapper.getLedgerBaseInfo(ids);
        if(CollUtil.isEmpty(ledgerBaseInfoList)){
            throw new BusinessException(CommonResponseEnum.FAIL,"查询台账为空");
        }
        Map<String,LedgerBaseInfo> ledgerBaseInfoMap = ledgerBaseInfoList.stream().collect(Collectors.toMap(LedgerBaseInfo::getLineId,line->line));
        result.getRecords().forEach(it->{
            LedgerBaseInfo ledgerBaseInfo = ledgerBaseInfoMap.get(it.getMonitorId());
            it.setMonitorName(ledgerBaseInfo.getLineName());
            it.setStationName(ledgerBaseInfo.getStationName());
            it.setObjName(ledgerBaseInfo.getObjName());
            it.setVAvgValue(BigDecimal.valueOf(it.getVAvgValue()*1000).setScale(2,RoundingMode.HALF_UP).doubleValue());
        });
        return result;
    }

    @Override
    public UpTableInfo tableInfo(LargeScreenCountParam param) {
        // 初始化结果对象
        UpTableInfo result = new UpTableInfo();
        List<String> dateList = new ArrayList<>();
        List<UpTableInfo.Inner> innerList = new ArrayList<>();

        // 1. 获取线路ID和台账基础信息
        List<String> lineIds = commGeneralService.getRunLineIdsByDept(param.getDeptId());
        if(CollUtil.isEmpty(lineIds)){
            throw new BusinessException(CommonResponseEnum.FAIL,"当前部门未绑定监测点");
        }
        List<LedgerBaseInfo> ledgerBaseInfoList = ledgerScaleMapper.getLedgerBaseInfo(lineIds);

        if (CollUtil.isEmpty(ledgerBaseInfoList)) {
            throw new BusinessException(CommonResponseEnum.FAIL, "查询台账为空");
        }

        // 2. 构建线路ID到名称的映射 & 提取线路名称列表
        Map<String, LedgerBaseInfo> ledgerBaseInfoMap = ledgerBaseInfoList.stream()
                .collect(Collectors.toMap(LedgerBaseInfo::getLineId, Function.identity()));
        List<String> ledgerList = ledgerBaseInfoList.stream().map(it-> {
            if(StrUtil.isBlank(it.getObjName())){
              return it.getLineName();
            }
            return strTranslate(it.getObjName());

        }).collect(Collectors.toList());

        // 3. 处理日期范围
        DateTime start = DateUtil.beginOfDay(DateUtil.parse(param.getSearchBeginTime()));
        DateTime end = DateUtil.endOfDay(DateUtil.parse(param.getSearchEndTime()));
        long dayDiff = DateUtil.betweenDay(start, end, false);

        // 确定日期范围和格式
        DateRange dateRange;
        String dateFormat;
        if (dayDiff <= 31) {
            dateRange = DateUtil.range(start, end, DateField.DAY_OF_MONTH);
            dateFormat = DAY_FORMAT;
        } else {
            dateRange = DateUtil.range(start, end, DateField.MONTH);
            dateFormat = MONTH_FORMAT;
        }

        // 4. 查询数据
        LambdaQueryWrapper<UpHarmonicDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.between(UpHarmonicDetail::getStartTime, start, end)
                .in(UpHarmonicDetail::getMonitorId, lineIds)
                .orderByDesc(UpHarmonicDetail::getStartTime);
        List<UpHarmonicDetail> data = this.list(queryWrapper);

        // 5. 处理数据（分空数据和非空数据情况）
        if (CollUtil.isEmpty(data)) {
            // 无数据时填充默认值
            fillDefaultData(dateRange, dateFormat, ledgerBaseInfoList, dateList, innerList);
        } else {
            // 有数据时按日期和线路分组统计
            processExistingData(dateRange, dateFormat, ledgerBaseInfoMap, data, dateList, innerList);
        }

        // 6. 设置结果
        result.setDate(dateList);
        result.setMonitorList(ledgerList);
        result.setInner(innerList);
        return result;
    }

    /**
     * 填充默认数据（当查询结果为空时）
     */
    private void fillDefaultData(DateRange dateRange, String dateFormat,
                                 List<LedgerBaseInfo> ledgerList, List<String> dateList,
                                 List<UpTableInfo.Inner> innerList) {
        for (DateTime range : dateRange) {
            String time = DateUtil.format(range, dateFormat);
            dateList.add(time);

            ledgerList.forEach(line -> {
                UpTableInfo.Inner inner = new UpTableInfo.Inner();
                inner.setDate(time);
                inner.setMonitorName(StrUtil.isNotBlank(line.getObjName())?strTranslate(line.getObjName()):line.getLineName());
                inner.setLineId(line.getLineId());
                inner.setCount(0);
                innerList.add(inner);
            });
        }
    }

    /**
     * 处理查询到的数据
     */
    private void processExistingData(DateRange dateRange, String dateFormat,
                                     Map<String, LedgerBaseInfo> ledgerBaseInfoMap,
                                     List<UpHarmonicDetail> data,
                                     List<String> dateList,
                                     List<UpTableInfo.Inner> innerList) {
        // 按监控ID分组
        Map<String, List<UpHarmonicDetail>> upMonitorMap = data.stream()
                .collect(Collectors.groupingBy(UpHarmonicDetail::getMonitorId));

        Map<String, LedgerBaseInfo> temMap = ObjectUtil.cloneByStream(ledgerBaseInfoMap);

        for (DateTime range : dateRange) {
            String time = DateUtil.format(range, dateFormat);
            dateList.add(time);

            upMonitorMap.forEach((lineKey, details) -> {
                temMap.remove(lineKey);
                UpTableInfo.Inner inner = new UpTableInfo.Inner();
                inner.setDate(time);
                if(ledgerBaseInfoMap.containsKey(lineKey)){
                    LedgerBaseInfo ledgerBaseInfo = ledgerBaseInfoMap.get(lineKey);
                    inner.setMonitorName(StrUtil.isNotBlank(ledgerBaseInfo.getObjName())?strTranslate(ledgerBaseInfo.getObjName()):ledgerBaseInfo.getLineName());
                    inner.setLineId(ledgerBaseInfo.getLineId());
                }
                // 统计当前日期下的记录数
                long count = details.stream()
                        .filter(detail -> DateUtil.format(detail.getStartTime(),dateFormat).equals(time))
                        .count();
                inner.setCount((int) count);
                innerList.add(inner);
            });

            //针对未发生谐波放大的测点
            temMap.forEach((k,v)->{
                UpTableInfo.Inner inner = new UpTableInfo.Inner();
                inner.setDate(time);
                inner.setMonitorName(StrUtil.isNotBlank(v.getObjName())?strTranslate(v.getObjName()):v.getLineName());
                inner.setLineId(v.getLineId());
                inner.setCount(0);
                innerList.add(inner);
            });
        }
    }


    private String strTranslate(String str){
       return str.replace("无锡市", "").replace("无锡", "");
    }


    /**
     * 计算并保存电压变化率数据
     */
    private List<DataVUp> calculateAndSaveDataVUp(String date,Map<String,Map<String, Double>> avgVMap) {
        InfluxQueryWrapper influxQueryWrapperV = new InfluxQueryWrapper(DataV.class);
        influxQueryWrapperV.between(DataV::getTime, date.concat(InfluxDBTableConstant.START_TIME), date.concat(InfluxDBTableConstant.END_TIME))
                .eq(DataV::getValueType, InfluxDBTableConstant.CP95)
                .ne(DataV::getPhaseType, InfluxDBTableConstant.PHASE_TYPE_T);

        List<DataV> dataVList = dataVMapper.selectByQueryWrapper(influxQueryWrapperV);
        if(CollUtil.isEmpty(dataVList)){
            log.error("data_v谐波放大算法查询原始数据为空！");
        }
        Map<String, List<DataV>> lineVMap = dataVList.stream()
                .collect(Collectors.groupingBy(DataV::getLineId));

        List<DataVUp> dataVUpList = new ArrayList<>();
        lineVMap.forEach((lineId, list) -> {
            // 计算所有字段的平均值（V1-V50）
            Map<String, Double> avgMap = calculateFieldAveragesV(list, 50);
            avgVMap.put(lineId,avgMap);
            // 按相别分组处理
            Map<String, List<DataV>> phaseList = list.stream()
                    .collect(Collectors.groupingBy(DataV::getPhaseType));

            phaseList.forEach((phase, pList) -> {
                pList.forEach(dataV -> {
                    DataVUp dataVUp = new DataVUp();
                    dataVUp.setPhasicType(phase);
                    dataVUp.setTime(dataV.getTime());
                    dataVUp.setLineId(dataV.getLineId());
                    dataVUp.setValueType(dataV.getValueType());

                    // 动态设置 V1-V50 的相对变化率
                    avgMap.forEach((field, avg) -> {
                        try {
                            // 获取 DataV 的当前字段值
                            Method getter = DataV.class.getMethod("get" + field);
                            double value = (double) getter.invoke(dataV);

                            // 计算相对变化率
                            double relativeChange = (avg == 0) ? 0 :
                                    BigDecimal.valueOf((value - avg) / avg)
                                            .setScale(6, RoundingMode.HALF_UP)
                                            .doubleValue();

                            // 设置到 DataVUp
                            Method setter = DataVUp.class.getMethod("set" + field, Double.class);
                            setter.invoke(dataVUp, relativeChange);

                            // 判断是否为异常值
                            if (specificHarmonicOrders.contains(getHarmonicOrderFromField(field))
                                    && relativeChange > voltageChangeRateThreshold) {
                                dataVUp.setAbnormalFlag(1);
                            } else if (dataVUp.getAbnormalFlag() == null) {
                                dataVUp.setAbnormalFlag(0);
                            }
                        } catch (NoSuchMethodException e) {
                            log.error("字段 {} 的 getter/setter 方法不存在", field, e);
                        } catch (Exception e) {
                            log.error("反射调用字段 {} 失败: {}", field, e.getMessage(), e);
                        }
                    });
                    dataVUpList.add(dataVUp);
                });
            });
        });

        if(CollUtil.isNotEmpty(dataVUpList)) {
            List<DataVUp> result = dataVUpList.stream()
                    .sorted(Comparator.comparing(DataVUp::getTime).thenComparing(DataVUp::getPhasicType))
                    .collect(Collectors.toList());
            dataVUpToMapper.insertBatch(result);
        }

        return dataVUpList;
    }

    /**
     * 计算并保存电流变化率数据
     */
    private List<DataIUp> calculateAndSaveDataIUp(String date,Map<String,Map<String, Double>> avgIMap) {
        InfluxQueryWrapper influxQueryWrapperI = new InfluxQueryWrapper(DataI.class);
        influxQueryWrapperI.between(DataI::getTime, date.concat(InfluxDBTableConstant.START_TIME), date.concat(InfluxDBTableConstant.END_TIME))
                .eq(DataI::getValueType, InfluxDBTableConstant.CP95)
                .ne(DataI::getPhaseType, InfluxDBTableConstant.PHASE_TYPE_T);

        List<DataI> dataIList = dataIMapper.selectByQueryWrapper(influxQueryWrapperI);
        if(CollUtil.isEmpty(dataIList)){
            log.error("data_i谐波放大算法查询原始数据为空！");
        }
        Map<String, List<DataI>> lineIMap = dataIList.stream()
                .collect(Collectors.groupingBy(DataI::getLineId));

        List<DataIUp> dataIUpList = new ArrayList<>();
        lineIMap.forEach((lineId, list) -> {
            // 计算所有字段的平均值（I1-I50）
            Map<String, Double> avgMap = calculateFieldAveragesI(list, 50);
            avgIMap.put(lineId,avgMap);

            // 按相别分组处理
            Map<String, List<DataI>> phaseList = list.stream()
                    .collect(Collectors.groupingBy(DataI::getPhaseType));

            phaseList.forEach((phase, pList) -> {
                pList.forEach(dataI -> {
                    DataIUp dataIUp = new DataIUp();
                    dataIUp.setPhasicType(phase);
                    dataIUp.setTime(dataI.getTime());
                    dataIUp.setLineId(dataI.getLineId());
                    dataIUp.setValueType(dataI.getValueType());

                    // 动态设置 I1-I50 的相对变化率
                    avgMap.forEach((field, avg) -> {
                            try {
                                // 获取 DataI 的当前字段值
                                Method getter = DataI.class.getMethod("get" + field);
                                double value = (double) getter.invoke(dataI);
                                double relativeChange = 3.1415926;
                                if(value>0.01){
                                    // 计算相对变化率
                                    relativeChange = (avg == 0) ? 0 :
                                            BigDecimal.valueOf(Math.abs(value - avg) / avg)
                                                    .setScale(6, RoundingMode.HALF_UP)
                                                    .doubleValue();
                                }



                                // 设置到 DataIUp
                                Method setter = DataIUp.class.getMethod("set" + field, Double.class);
                                setter.invoke(dataIUp, relativeChange);
                            } catch (NoSuchMethodException e) {
                                log.error("字段 {} 的 getter/setter 方法不存在", field, e);
                            } catch (Exception e) {
                                log.error("反射调用字段 {} 失败: {}", field, e.getMessage(), e);
                            }

                    });
                    dataIUpList.add(dataIUp);

                });
            });
        });

        if(CollUtil.isNotEmpty(dataIUpList)) {
            List<DataIUp> result = dataIUpList.stream()
                    .sorted(Comparator.comparing(DataIUp::getTime).thenComparing(DataIUp::getPhasicType))
                    .collect(Collectors.toList());
            dataIUpToMapper.insertBatch(result);
        }

        return dataIUpList;
    }

    /**
     * 分析谐波放大事件并保存到up_harmonic_detail表
     */
    private void analyzeAndSaveHarmonicEvents(List<DataVUp> dataVUpList, List<DataIUp> dataIUpList,Map<String,Map<String, Double>> avgVMap,Map<String,Map<String, Double>> avgIMap) {
        // 按线路、时间、相别分组电流数据，便于查询
        Map<String, DataIUp> iUpMap = dataIUpList.stream()
                .collect(Collectors.toMap(
                        item -> item.getLineId() + StrUtil.C_UNDERLINE + item.getTime() + StrUtil.C_UNDERLINE + item.getPhasicType(),
                        item -> item
                ));

        // 存储所有异常点信息
        Map<String, List<AnomalyInfo>> anomalyMap = new HashMap<>();

        // 遍历电压数据，检查异常点
        Set<String> lineSet = new HashSet<>();
        for (DataVUp vUp : dataVUpList) {
            lineSet.add(vUp.getLineId());
            String key = vUp.getLineId() + StrUtil.C_UNDERLINE + vUp.getTime() + StrUtil.C_UNDERLINE + vUp.getPhasicType();

            // 检查是否有对应的电流数据
            if (!iUpMap.containsKey(key)) {
                continue;
            }

            DataIUp iUp = iUpMap.get(key);
            // 检查每个特定谐波次数
            for (int order : specificHarmonicOrders) {
                try {
                    // 获取电压变化率
                    String vField = "v" + order;
                    Method vGetter = DataVUp.class.getMethod("get" + Character.toUpperCase(vField.charAt(0)) + vField.substring(1));
                    double vChangeRate = (double) vGetter.invoke(vUp);

                    // 获取电流变化率
                    String iField = "i" + order;
                    Method iGetter = DataIUp.class.getMethod("get" + Character.toUpperCase(iField.charAt(0)) + iField.substring(1));
                    double iChangeRate = (double) iGetter.invoke(iUp);

                    // 检查是否满足异常条件
                    if (vChangeRate > voltageChangeRateThreshold && iChangeRate < currentChangeRateThreshold && iChangeRate!=3.1415926) {
                        String anomalyKey = vUp.getLineId() + StrUtil.C_UNDERLINE + vUp.getPhasicType() + StrUtil.C_UNDERLINE + order;

                        AnomalyInfo info = new AnomalyInfo();
                        info.setLineId(vUp.getLineId());
                        info.setPhase(vUp.getPhasicType());
                        info.setHarmonicOrder(order);
                        info.setTime(vUp.getTime());
                        info.setVoltageChangeRate(vChangeRate);
                        info.setCurrentChangeRate(iChangeRate);

                        if (!anomalyMap.containsKey(anomalyKey)) {
                            anomalyMap.put(anomalyKey, new ArrayList<>());
                        }
                        anomalyMap.get(anomalyKey).add(info);
                    }
                } catch (Exception e) {
                    log.error("分析谐波次数 {} 时发生错误", order, e);
                }
            }
        }

        List<LedgerBaseInfo> ledgerBaseInfoList = ledgerScaleMapper.getLedgerBaseInfo(new ArrayList<>(lineSet));
        Map<String,LedgerBaseInfo> ledgerBaseInfoMap = ledgerBaseInfoList.stream().collect(Collectors.toMap(LedgerBaseInfo::getLineId,Function.identity()));

        // 处理异常点，生成谐波放大事件
        List<UpHarmonicDetail> harmonicDetails = new ArrayList<>();

        for (List<AnomalyInfo> anomalies : anomalyMap.values()) {
            if (anomalies.size() < continuousAnomalyCount) {
                continue; // 连续异常点数量不足，不生成事件
            }

            // 按时间排序
            List<AnomalyInfo> sortedAnomalies = anomalies.stream()
                    .sorted(Comparator.comparing(AnomalyInfo::getTime))
                    .collect(Collectors.toList());

            // 检查是否连续
            List<List<AnomalyInfo>> infoList =findAllContinuousAnomalies(sortedAnomalies,ledgerBaseInfoMap);

            if (!infoList.isEmpty()) {
                for (List<AnomalyInfo> temList : infoList) {
                    AnomalyInfo first = temList.get(0);
                    AnomalyInfo last = temList.get(temList.size() - 1);

                    // 创建谐波放大事件记录
                    UpHarmonicDetail detail = new UpHarmonicDetail();
                    detail.setId(IdWorker.get32UUID());
                    detail.setMonitorId(first.getLineId());
                    detail.setPhase(first.getPhase());
                    detail.setHarmonicCount(first.getHarmonicOrder());

                    // 转换时间格式
                    detail.setStartTime(LocalDateTime.ofInstant(first.getTime(), ZoneId.systemDefault()));
                    detail.setEndTime(LocalDateTime.ofInstant(last.getTime(), ZoneId.systemDefault()));

                    // 计算持续时间(秒)
                    long duration = ChronoUnit.SECONDS.between(
                            detail.getStartTime(),
                            detail.getEndTime()
                    );
                    detail.setDuration((double) duration);
                    detail.setVAvgValue(avgVMap.get(first.lineId).get("V"+first.getHarmonicOrder()));
                    detail.setIAvgValue(avgIMap.get(first.lineId).get("I"+first.getHarmonicOrder()));

                    detail.setCreateTime(LocalDateTime.now());
                    if(first.getHarmonicOrder()>5){
                        detail.setUpScheme("选取5% - 6%电抗率");
                    }else {
                        detail.setUpScheme("选取12%的电抗率（或选取5% - 6%与12%两种电抗率混装方式）");
                    }

                    harmonicDetails.add(detail);

                    log.info("发现谐波放大事件: 监测点={}, 谐波次数={}, 持续时间={}秒, 开始时间={}",
                            first.getLineId(), first.getHarmonicOrder(), duration, detail.getStartTime());
                }
            }
        }

        // 批量保存事件
        if (CollUtil.isNotEmpty(harmonicDetails)) {
            this.saveBatch(harmonicDetails);
        }
    }

    /**
     * 检查数据是否连续（每分钟一条记录）
     */
    /**
     * 查找所有连续10条记录（每条间隔50~70秒）的事件
     */
    private List<List<AnomalyInfo>> findAllContinuousAnomalies(List<AnomalyInfo> anomalies,Map<String,LedgerBaseInfo> ledgerBaseInfoMap) {
        List<List<AnomalyInfo>> groups = new ArrayList<>();
        List<AnomalyInfo> currentGroup = new ArrayList<>();

        int timeInterval = ledgerBaseInfoMap.get(anomalies.get(0).getLineId()).getTimeInterval();

        for (AnomalyInfo current : anomalies) {
            if (currentGroup.isEmpty()) {
                currentGroup.add(current);
            } else {
                AnomalyInfo lastInGroup = currentGroup.get(currentGroup.size() - 1);
                long minutesDiff = ChronoUnit.MINUTES.between(lastInGroup.getTime(), current.getTime());

                if (minutesDiff == timeInterval) {
                    currentGroup.add(current);
                } else {
                    // 不连续，检查当前组是否满足 >=10
                    if (currentGroup.size() >= continuousAnomalyCount) {
                        groups.add(new ArrayList<>(currentGroup));
                    }
                    // 重置当前组
                    currentGroup.clear();
                    currentGroup.add(current);
                }
            }
        }
        return groups;
    }

    /**
     * 从字段名中提取谐波次数
     */
    private int getHarmonicOrderFromField(String field) {
        try {
            return Integer.parseInt(field.substring(1));
        } catch (Exception e) {
            return -1;
        }
    }

    /**
     * 计算 DataV 对象中 V1-Vmax 的平均值
     */
    private Map<String, Double> calculateFieldAveragesV(List<DataV> list, Integer maxField) {
        Map<String, Double> avgMap = new HashMap<>();
        for (int i = 1; i <= maxField; i++) {
            String field = "V" + i;
            double avg = list.stream()
                    .mapToDouble(dataV -> {
                        try {
                            Method getter = DataV.class.getMethod("get" + field);
                            return (double) getter.invoke(dataV);
                        } catch (Exception e) {
                            return 0d;
                        }
                    })
                    .average()
                    .orElse(0);
            avgMap.put(field, avg);
        }
        return avgMap;
    }

    /**
     * 计算 DataI 对象中 I1-Imax 的平均值
     */
    private Map<String, Double> calculateFieldAveragesI(List<DataI> list, Integer maxField) {
        Map<String, Double> avgMap = new HashMap<>();
        for (int i = 1; i <= maxField; i++) {
            String field = "I" + i;
            double avg = list.stream()
                    .mapToDouble(dataI -> {
                        try {
                            Method getter = DataI.class.getMethod("get" + field);
                            return (double) getter.invoke(dataI);
                        } catch (Exception e) {
                            return 0d;
                        }
                    })
                    .average()
                    .orElse(0);
            avgMap.put(field, avg);
        }
        return avgMap;
    }

    /**
     * 内部类：用于临时存储异常点信息
     */
    @Data
    private static class AnomalyInfo {
        private String lineId;
        private String phase;
        private int harmonicOrder;
        private Instant time;
        private double voltageChangeRate;
        private double currentChangeRate;

    }
}