package com.ruoyi.system.util;

import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.system.domain.EpsNodeBandwidth;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

public class EchartsDataConverter {

    /**
     * 转换为ECharts折线图数据
     * @param dataList 原始数据列表
     * @return { lineXData: [], data: [] }
     */
    public static Map<String, Object> convertToLineChart(
            List<EpsNodeBandwidth> dataList,
            String bandwidthType, String nodeName, String startTime, String endTime, ChronoUnit timeUnit
    ) {
        // 定义时间格式化器
        SimpleDateFormat sdf = new SimpleDateFormat(
                timeUnit == ChronoUnit.DAYS ? "yyyy-MM-dd" : "yyyy-MM"
        );
        // 2. 生成完整时间序列
        List<Date> fullSeries = generateTimeSeries(DateUtils.parseDate(startTime), DateUtils.parseDate(endTime), timeUnit);
        // 过滤+排序
        List<EpsNodeBandwidth> validList = dataList.stream()
                .filter(item ->
                        item.getCreateTime() != null &&
                                item.getBandwidthResult() != null &&
                                (bandwidthType == null || bandwidthType.equals(item.getBandwidthType())) &&
                                (nodeName == null || nodeName.equals(item.getNodeName()))
                )
                .sorted(Comparator.comparing(EpsNodeBandwidth::getCreateTime))
                .collect(Collectors.toList());

        // 3. 创建数据映射
        Map<Date, BigDecimal> dataMap = createDataMap(validList);
        // 4. 补全数据
        List<String> xData = new ArrayList<>();
        List<BigDecimal> yData = new ArrayList<>();

        for (Date time : fullSeries) {
            xData.add(sdf.format(time));
            yData.add(dataMap.getOrDefault(time, BigDecimal.ZERO));
        }
        Map map = new HashMap();
        map.put("lineXData", xData);
        map.put("data", yData);
        return map;
    }
    private static List<Date> generateTimeSeries(Date start, Date end, ChronoUnit unit) {
        List<Date> series = new ArrayList<>();
        Calendar cal = Calendar.getInstance();
        cal.setTime(start);

        // 重置到时间单位起始点
        switch (unit) {
            case DAYS:
                cal.set(Calendar.HOUR_OF_DAY, 0);
                cal.set(Calendar.MINUTE, 0);
                cal.set(Calendar.SECOND, 0);
                cal.set(Calendar.MILLISECOND, 0);
                break;
            case MONTHS:
                cal.set(Calendar.DAY_OF_MONTH, 1);
                cal.set(Calendar.HOUR_OF_DAY, 0);
                cal.set(Calendar.MINUTE, 0);
                cal.set(Calendar.SECOND, 0);
                cal.set(Calendar.MILLISECOND, 0);
                break;
            default:
                throw new IllegalArgumentException("仅支持 DAYS 或 MONTHS 单位");
        }


        // 生成序列
        while (!cal.getTime().after(end)) {
            series.add(cal.getTime());

            switch (unit) {
                case DAYS:
                    cal.add(Calendar.DATE, 1); // 按天递增
                    break;
                case MONTHS:
                    cal.add(Calendar.MONTH, 1); // 按月递增
                    break;
            }
        }

        return series;
    }
    private static Map<Date, BigDecimal> createDataMap(List<EpsNodeBandwidth> dataList) {
        return dataList.stream()
                .collect(Collectors.toMap(
                        EpsNodeBandwidth::getCreateTime,
                        EpsNodeBandwidth::getBandwidthResult,
                        (v1, v2) -> v1 // 如果参数冲突 保留有值的 补充x轴
                ));
    }
}
