package com.njcn.harmonic.service.influxdb.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.njcn.common.utils.HarmonicTimesUtil;
import com.njcn.dataProcess.param.LineCountEvaluateParam;
import com.njcn.dataProcess.pojo.dto.DataIDto;
import com.njcn.harmonic.service.influxdb.IDataI;
import com.njcn.influx.constant.InfluxDbSqlConstant;
import com.njcn.influx.imapper.DataIMapper;
import com.njcn.influx.pojo.po.DataI;
import com.njcn.influx.query.InfluxQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @author wr
 * @description
 * @date 2026/7/1 10:49
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class InfluxdbDataIImpl implements IDataI {
    private final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.systemDefault());

    private final DataIMapper dataIMapper;

    private static final Map<String, String> PHASE_MAPPING = new HashMap<String, String>() {{
        put("AB", "A");
        put("BC", "B");
        put("CA", "C");
        put("M", "T");
    }};

    @Override
    public List<DataIDto> getRawData(LineCountEvaluateParam lineParam) {
        List<DataIDto> result = new ArrayList<>();
        List<DataI> list = getMinuteDataI(lineParam);;
        list.forEach(item->{
            DataIDto dto = new DataIDto();
            BeanUtils.copyProperties(item,dto);
            dto.setMinTime(DATE_TIME_FORMATTER.format(item.getTime()));
            result.add(dto);
        });
        return result;
    }

    /**
     * 按监测点集合、时间条件获取dataI分钟数据
     * timeMap参数来判断是否进行数据处理 timeMap为空则不进行数据处理
     * 需要进行剔除异常数据时,这里会有三种情况判断
     * 1.无异常数据，则直接返回集合；
     * 2.异常数据和无异常数据参杂，剔除异常数据，只计算正常数据；
     * 3.全是异常数据，则使用异常数据进行计算，但是日表中需要标记出来，此数据有异常
     */
    public List<DataI> getMinuteDataI(LineCountEvaluateParam lineParam) {
        List<DataI> dataList;
        List<DataI> result = new ArrayList<>();
        InfluxQueryWrapper influxQueryWrapper = new InfluxQueryWrapper(DataI.class);
        influxQueryWrapper.samePrefixAndSuffix(InfluxDbSqlConstant.I, InfluxDbSqlConstant.I, HarmonicTimesUtil.harmonicTimesList(1, 50, 1));
        influxQueryWrapper.regular(DataI::getLineId, lineParam.getLineId())
                .select(DataI::getLineId)
                .select(DataI::getPhaseType)
                .select(DataI::getValueType)
                .select(DataI::getINeg)
                .select(DataI::getIPos)
                .select(DataI::getIThd)
                .select(DataI::getIUnbalance)
                .select(DataI::getIZero)
                .select(DataI::getRms)
                .select(DataI::getQualityFlag)
                .select(DataI::getAbnormalFlag)
                .between(DataI::getTime, lineParam.getStartTime(), lineParam.getEndTime())
                .eq(DataI::getQualityFlag,"0");
        if(CollUtil.isNotEmpty(lineParam.getPhasicType())){
            influxQueryWrapper.regular(DataI::getPhaseType,lineParam.getPhasicType());
        }

        List<DataI> list = dataIMapper.selectByQueryWrapper(influxQueryWrapper);
        if(CollUtil.isNotEmpty(list)){
            //过滤掉暂态事件影响的数据 true过滤 false不过滤
            if (lineParam.getDataType()) {
                dataList = list.stream().filter(item -> Objects.isNull(item.getAbnormalFlag())).collect(Collectors.toList());
            } else {
                dataList = list;
            }
            Map<String,List<DataI>> lineMap = dataList.stream().collect(Collectors.groupingBy(DataI::getLineId));
            //有异常数据
            if (CollectionUtil.isNotEmpty(lineParam.getAbnormalTime())) {
                lineMap.forEach((k,v)->{
                    List<String> timeList = lineParam.getAbnormalTime().get(k);
                    //有异常数据,当前监测点自身的异常数据
                    if (CollectionUtil.isNotEmpty(timeList)) {
                        List<DataI> filterList = v.stream().filter(item -> !timeList.contains(DATE_TIME_FORMATTER.format(item.getTime()))).collect(Collectors.toList());
                        //1.过滤掉异常数据后还有正常数据，则用正常数据计算
                        if (CollectionUtil.isNotEmpty(filterList)) {
                            result.addAll(filterList);
                        }
                        //2.过滤掉异常数据后没有正常数据，则用所有异常数据计算，但是需要标记数据为异常的
                        else {
                            v.parallelStream().forEach(item -> item.setQualityFlag("1"));
                            result.addAll(v);
                        }
                    }
                    //没有异常数据，则使用原数据
                    else {
                        result.addAll(v);
                    }
                });
            }
            //没有异常数据，则使用原数据
            else {
                result.addAll(dataList);
            }
        }
        if (CollectionUtil.isNotEmpty(result)) {
            result.forEach(item -> {
                String newType = PHASE_MAPPING.get(item.getPhaseType());
                if (newType != null) {
                    item.setPhaseType(newType);
                }
            });
        }
        return result;
    }
}
