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.DataHarmDto;
import com.njcn.harmonic.service.influxdb.IDataInHarmV;
import com.njcn.influx.constant.InfluxDbSqlConstant;
import com.njcn.influx.imapper.DataInHarmVMapper;
import com.njcn.influx.pojo.po.DataInHarmV;
import com.njcn.influx.query.InfluxQueryWrapper;
import lombok.RequiredArgsConstructor;
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;


/**
 * Description:
 * Date: 2024/11/18  14:33【需求编号】
 *
 * @author clam
 * @version V1.0.0
 */
@Service
@RequiredArgsConstructor
public class InfluxdbDataInharmVImpl  implements IDataInHarmV {

    private final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.systemDefault());
    private final DataInHarmVMapper DataInHarmVMapper;

    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<DataHarmDto> getRawData(LineCountEvaluateParam lineParam) {
        List<DataHarmDto> result = new ArrayList<>();
        List<DataInHarmV> list = getMinuteData(lineParam);
        list.forEach(item->{
            DataHarmDto dto = new DataHarmDto();
            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<DataInHarmV> getMinuteData(LineCountEvaluateParam lineParam) {
        List<DataInHarmV> dataList;
        List<DataInHarmV> result = new ArrayList<>();
        InfluxQueryWrapper influxQueryWrapper = new InfluxQueryWrapper(DataInHarmV.class);
        influxQueryWrapper.samePrefixAndSuffix(InfluxDbSqlConstant.V, InfluxDbSqlConstant.V, HarmonicTimesUtil.harmonicTimesList(1, 50, 1));
        influxQueryWrapper.regular(DataInHarmV::getLineId, lineParam.getLineId())
                .select(DataInHarmV::getLineId)
                .select(DataInHarmV::getPhaseType)
                .select(DataInHarmV::getValueType)
                .select(DataInHarmV::getQualityFlag)
                .select(DataInHarmV::getAbnormalFlag)
                .between(DataInHarmV::getTime, lineParam.getStartTime(), lineParam.getEndTime())
                .eq(DataInHarmV::getQualityFlag,"0");
        if(CollUtil.isNotEmpty(lineParam.getPhasicType())){
            influxQueryWrapper.regular(DataInHarmV::getPhaseType,lineParam.getPhasicType());
        }
        List<DataInHarmV> list = DataInHarmVMapper.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<DataInHarmV>> lineMap = dataList.stream().collect(Collectors.groupingBy(DataInHarmV::getLineId));
            //有异常数据
            if (CollectionUtil.isNotEmpty(lineParam.getAbnormalTime())) {
                lineMap.forEach((k,v)->{
                    List<String> timeList = lineParam.getAbnormalTime().get(k);
                    //有异常数据,当前监测点自身的异常数据
                    if (CollectionUtil.isNotEmpty(timeList)) {
                        List<DataInHarmV> 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;
    }
}
