package com.njcn.device.pq.utils;

import cn.hutool.core.collection.CollectionUtil;
import com.njcn.device.pq.pojo.po.LineDataIntegrity;
import com.njcn.device.pq.pojo.po.TerminalOnlineRateData;
import com.njcn.device.pq.pojo.vo.LineIntegrityDataVO;
import com.njcn.device.pq.pojo.vo.TerminalOnlineRateDataVO;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 监测点完整性、终端在线率
 *
 * @author yzh
 * @date 2022/9/26
 */

public class DataStatisticsUtil {

    /**
     * 获取监测点数据完整性
     *
     * @param percentageOfCompleteDatas influxdb数据
     * @param lineList                  监测点集合
     */
    public static void getLineDataIntegrity(List<LineDataIntegrity> percentageOfCompleteDatas, List<LineIntegrityDataVO> lineList) {

        if (CollectionUtil.isNotEmpty(percentageOfCompleteDatas)) {

            // 根据监测点id分类
            Map<String, List<LineDataIntegrity>> groupByLineId = percentageOfCompleteDatas.stream().collect(Collectors.groupingBy(LineDataIntegrity::getLineId));
            // 新建集合处理数据
            List<LineDataIntegrity> lineIntegrityData = new ArrayList<>();
            // 获取map中的key（监测点id集合）
            Set<String> lineIds = groupByLineId.keySet();

            for (String lineId : lineIds) {
                // 创建对象处理数据
                LineDataIntegrity integrity = new LineDataIntegrity();
                // 期望值
                Double due = 0.0;
                // 实际值
                Double real = 0.0;

                // 取出值
                List<LineDataIntegrity> lineDataIntegrities = groupByLineId.get(lineId);

                for (LineDataIntegrity dataIntegrity : lineDataIntegrities) {
                    due += dataIntegrity.getDue();
                    real += dataIntegrity.getReal();
                }
                // 求出监测点数据完整性
                double integrityDataDouble = real / due * 100;
                String integrityDataString = String.format("%.2f", integrityDataDouble);
                integrity.setIntegrityData(Double.parseDouble(integrityDataString));
                integrity.setLineId(lineId);
                lineIntegrityData.add(integrity);
            }

            lineList = lineList.stream().peek(integrityDataVO -> {
                for (LineDataIntegrity lineIntegrityDatum : lineIntegrityData) {
                    if (integrityDataVO.getId().equals(lineIntegrityDatum.getLineId())) {
                        if (lineIntegrityDatum.getIntegrityData() != null) {
                            integrityDataVO.setIntegrityData(lineIntegrityDatum.getIntegrityData());
                        } else {
                            // 为空则给对应的监测点的监测点合设置为魔数
                            integrityDataVO.setIntegrityData(3.14159);
                        }
                    }
                }
            }).collect(Collectors.toList());
        } else {
            lineList = lineList.stream().peek(integrityDataVO -> integrityDataVO.setIntegrityData(3.14159)).collect(Collectors.toList());
        }
    }

    /**
     * 获取区域数据完整性
     *
     * @param percentageOfCompleteDatas
     */
    public static double getAreaDataIntegrity(List<LineDataIntegrity> percentageOfCompleteDatas) {
        double data = 0.0;
        if (CollectionUtil.isNotEmpty(percentageOfCompleteDatas)) {
            // 按时间分类
            Map<String, List<LineDataIntegrity>> groupByTime = percentageOfCompleteDatas.stream().peek(lineDataIntegrity -> {
                double integrityDataDouble = lineDataIntegrity.getReal() / lineDataIntegrity.getDue() * 100;
                String integrityDataString = String.format("%.2f", integrityDataDouble);
                lineDataIntegrity.setIntegrityData(Double.parseDouble(integrityDataString));
            }).collect(Collectors.groupingBy(LineDataIntegrity::getTime));
            Set<String> times = groupByTime.keySet();
            for (String time : times) {
                double integrityData = 0.0;
                List<LineDataIntegrity> lineDataIntegrities = groupByTime.get(time);
                int size = lineDataIntegrities.size();
                for (LineDataIntegrity lineData : lineDataIntegrities) {
                    integrityData += lineData.getIntegrityData();
                }

                Double integrityDataDouble = (integrityData / size);
                String integrityDataString = String.format("%.2f", integrityDataDouble);
                data = Double.parseDouble(integrityDataString);
            }
        } else {
            data = 3.14159;
        }
        return data;
    }

    /**
     * 获取终端在线率
     *
     * @param terminalOnlineRateList
     * @param deviceList
     */
    public static void getTerminalOnlineRateData(List<TerminalOnlineRateData> terminalOnlineRateList, List<TerminalOnlineRateDataVO> deviceList) {

        if (CollectionUtil.isNotEmpty(terminalOnlineRateList)) {
            // 根据监测点id分类

            deviceList = deviceList.stream().peek(onlineRateDataVO -> {
                boolean flag = false;
                for (TerminalOnlineRateData onlineRateData : terminalOnlineRateList) {
                    if (onlineRateDataVO.getId().equals(onlineRateData.getDevId())) {
                        flag = true;
                        onlineRateDataVO.setOnlineMin(onlineRateData.getOnlineMin());
                        onlineRateDataVO.setOfflineMin(onlineRateData.getOfflineMin());
                        // 根据onlineMin和offlineMin计算在线率
                        Double onlineRate = calculateOnlineRate(onlineRateData.getOnlineMin(), onlineRateData.getOfflineMin());
                        onlineRateDataVO.setOnlineRate(onlineRate);
                        break;
                    }
                }
                if (!flag) {
                    onlineRateDataVO.setOnlineRate(3.14159);
                    onlineRateDataVO.setOnlineMin(0);
                    onlineRateDataVO.setOfflineMin(0);
                }
            }).collect(Collectors.toList());
        } else {
            deviceList = deviceList.stream().peek(onlineRateDataVO -> {
                onlineRateDataVO.setOnlineRate(3.14159);
                onlineRateDataVO.setOnlineMin(0);
                onlineRateDataVO.setOfflineMin(0);
            }).collect(Collectors.toList());
        }
    }

    /**
     *
     * @param data
     * @return
     */
    public static Double dataLimits(Double data){
        return data>100?100:data;
    }

    /**
     * 根据在线分钟数和离线分钟数计算在线率
     * @param onlineMin 在线分钟数
     * @param offlineMin 离线分钟数
     * @return 在线率（保留两位小数，超过100则返回100）
     */
    public static Double calculateOnlineRate(Integer onlineMin, Integer offlineMin) {
        if (onlineMin == null || offlineMin == null) {
            return 3.14159;
        }
        long totalMin = onlineMin + offlineMin;
        if (totalMin == 0) {
            return 3.14159;
        }
        double rate = onlineMin * 100.0 / totalMin;
        // 保留两位小数
        rate = Math.round(rate * 100.0) / 100.0;
        return dataLimits(rate);
    }

    /**
     * 根据实际时间和期望时间计算数据完整性
     * @param realTime 实际时间
     * @param dueTime 期望时间
     * @return 数据完整性（保留两位小数，超过100则返回100）
     */
    public static Double calculateIntegrityRate(Integer realTime, Integer dueTime) {
        if (realTime == null || dueTime == null) {
            return 3.14159;
        }
        if (dueTime == 0) {
            return 3.14159;
        }
        double rate = realTime * 100.0 / dueTime;
        // 保留两位小数
        rate = Math.round(rate * 100.0) / 100.0;
        return dataLimits(rate);
    }

}


