package com.ruoyi.common.core.utils;


import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

public class SpeedUtils {

    public static class SpeedResult {
        private BigDecimal avgInSpeedGb;  // 平均输入速度 (Gb)
        private BigDecimal avgOutSpeedGb; // 平均输出速度 (Gb)
        private BigDecimal maxInSpeedGb;  // 最大输入速度 (Gb)
        private BigDecimal maxOutSpeedGb; // 最大输出速度 (Gb)
        private BigDecimal lastInSpeedGb; // 最后一个输入速度 (Gb)
        private BigDecimal lastOutSpeedGb;// 最后一个输出速度 (Gb)
        private String recommendedUnit;  // 基于平均值推荐的单位

        public SpeedResult(BigDecimal avgInSpeedGb, BigDecimal avgOutSpeedGb,
                           BigDecimal maxInSpeedGb, BigDecimal maxOutSpeedGb,
                           BigDecimal lastInSpeedGb, BigDecimal lastOutSpeedGb,
                           String recommendedUnit) {
            this.avgInSpeedGb = avgInSpeedGb;
            this.avgOutSpeedGb = avgOutSpeedGb;
            this.maxInSpeedGb = maxInSpeedGb;
            this.maxOutSpeedGb = maxOutSpeedGb;
            this.lastInSpeedGb = lastInSpeedGb;
            this.lastOutSpeedGb = lastOutSpeedGb;
            this.recommendedUnit = recommendedUnit;
        }

        // Getters
        public BigDecimal getAvgInSpeedGb() { return avgInSpeedGb; }
        public BigDecimal getAvgOutSpeedGb() { return avgOutSpeedGb; }
        public BigDecimal getMaxInSpeedGb() { return maxInSpeedGb; }
        public BigDecimal getMaxOutSpeedGb() { return maxOutSpeedGb; }
        public BigDecimal getLastInSpeedGb() { return lastInSpeedGb; }
        public BigDecimal getLastOutSpeedGb() { return lastOutSpeedGb; }
        public String getRecommendedUnit() { return recommendedUnit; }

        @Override
        public String toString() {
            return String.format(
                    "平均输入速度: %s Gb, 平均输出速度: %s Gb\n" +
                            "最大输入速度: %s Gb, 最大输出速度: %s Gb\n" +
                            "最后输入速度: %s Gb, 最后输出速度: %s Gb\n" +
                            "推荐单位(基于平均值): %s",
                    avgInSpeedGb.setScale(2, RoundingMode.HALF_UP),
                    avgOutSpeedGb.setScale(2, RoundingMode.HALF_UP),
                    maxInSpeedGb.setScale(2, RoundingMode.HALF_UP),
                    maxOutSpeedGb.setScale(2, RoundingMode.HALF_UP),
                    lastInSpeedGb.setScale(2, RoundingMode.HALF_UP),
                    lastOutSpeedGb.setScale(2, RoundingMode.HALF_UP),
                    recommendedUnit
            );
        }
    }

    public static SpeedResult calculateWithAverageBasedUnit(List<?> list,
                                                            String inSpeedField, String outSpeedField)
            throws NoSuchFieldException, IllegalAccessException {

        if (list == null || list.isEmpty()) {
            return new SpeedResult(
                    BigDecimal.ZERO, BigDecimal.ZERO,
                    BigDecimal.ZERO, BigDecimal.ZERO,
                    BigDecimal.ZERO, BigDecimal.ZERO,
                    "bit"
            );
        }

        BigDecimal totalInSpeedBit = BigDecimal.ZERO;
        BigDecimal totalOutSpeedBit = BigDecimal.ZERO;
        BigDecimal maxInSpeedGb = BigDecimal.ZERO;
        BigDecimal maxOutSpeedGb = BigDecimal.ZERO;
        BigDecimal lastInSpeedGb = BigDecimal.ZERO;
        BigDecimal lastOutSpeedGb = BigDecimal.ZERO;

        final BigDecimal GB_DIVISOR = new BigDecimal("1000000000");

        // 计算总和(bit)和Gb值
        for (Object obj : list) {
            try {
                java.lang.reflect.Field inField = obj.getClass().getDeclaredField(inSpeedField);
                java.lang.reflect.Field outField = obj.getClass().getDeclaredField(outSpeedField);

                inField.setAccessible(true);
                outField.setAccessible(true);

                BigDecimal inSpeedBit = (BigDecimal) inField.get(obj) == null ? BigDecimal.ZERO : (BigDecimal) inField.get(obj);
                BigDecimal outSpeedBit = (BigDecimal) outField.get(obj) == null ? BigDecimal.ZERO : (BigDecimal) outField.get(obj);

                // 累加bit值(用于计算平均值)
                totalInSpeedBit = totalInSpeedBit.add(inSpeedBit);
                totalOutSpeedBit = totalOutSpeedBit.add(outSpeedBit);

                // 转换为Gb并更新最大值
                BigDecimal inSpeedGb = inSpeedBit.divide(GB_DIVISOR, 0, RoundingMode.HALF_UP);
                BigDecimal outSpeedGb = outSpeedBit.divide(GB_DIVISOR, 0, RoundingMode.HALF_UP);

                maxInSpeedGb = maxInSpeedGb.max(inSpeedGb);
                maxOutSpeedGb = maxOutSpeedGb.max(outSpeedGb);

                // 记录最后一个值
                lastInSpeedGb = inSpeedGb;
                lastOutSpeedGb = outSpeedGb;
            } catch (Exception e) {
                throw new RuntimeException("无法获取速度字段值", e);
            }
        }

        // 计算Gb平均值
        BigDecimal size = new BigDecimal(list.size());
        BigDecimal avgInSpeedGb = totalInSpeedBit.divide(GB_DIVISOR, 0, RoundingMode.HALF_UP)
                .divide(size, 2, RoundingMode.HALF_UP);
        BigDecimal avgOutSpeedGb = totalOutSpeedBit.divide(GB_DIVISOR, 0, RoundingMode.HALF_UP)
                .divide(size, 2, RoundingMode.HALF_UP);

        // 基于平均值的较大值确定推荐单位
        BigDecimal maxAvgBit = avgInSpeedGb.compareTo(avgOutSpeedGb) > 0 ?
                avgInSpeedGb.multiply(GB_DIVISOR) :
                avgOutSpeedGb.multiply(GB_DIVISOR);

        String recommendedUnit;
        if (maxAvgBit.compareTo(new BigDecimal("1000000000")) >= 0) {
            recommendedUnit = "Gb";
        } else if (maxAvgBit.compareTo(new BigDecimal("1000000")) >= 0) {
            recommendedUnit = "Mb";
        } else{
            recommendedUnit = "Kb";
        }

        return new SpeedResult(
                avgInSpeedGb, avgOutSpeedGb,
                maxInSpeedGb, maxOutSpeedGb,
                lastInSpeedGb, lastOutSpeedGb,
                recommendedUnit
        );
    }
    // 工具方法：获取单位换算除数
    public static BigDecimal getDivisor(String unit) {
        switch (unit) {
            case "Gb": return new BigDecimal("1000000000");
            case "Mb": return new BigDecimal("1000000");
            case "Kb": return new BigDecimal("1000");
            default: return BigDecimal.ONE; // bit
        }
    }
    public static String calculateUnit(List<?> list,
                                                            String inSpeedField, String outSpeedField)
            throws NoSuchFieldException, IllegalAccessException {

        if (list == null || list.isEmpty()) {
            return null;
        }

        BigDecimal totalInSpeedBit = BigDecimal.ZERO;
        BigDecimal totalOutSpeedBit = BigDecimal.ZERO;
        BigDecimal maxInSpeedGb = BigDecimal.ZERO;
        BigDecimal maxOutSpeedGb = BigDecimal.ZERO;
        BigDecimal lastInSpeedGb = BigDecimal.ZERO;
        BigDecimal lastOutSpeedGb = BigDecimal.ZERO;

        final BigDecimal GB_DIVISOR = new BigDecimal("1000000000");

        // 计算总和(bit)和Gb值
        for (Object obj : list) {
            try {
                java.lang.reflect.Field inField = obj.getClass().getDeclaredField(inSpeedField);
                java.lang.reflect.Field outField = obj.getClass().getDeclaredField(outSpeedField);

                inField.setAccessible(true);
                outField.setAccessible(true);

                BigDecimal inSpeedBit = (BigDecimal) inField.get(obj) == null ? BigDecimal.ZERO : (BigDecimal) inField.get(obj);
                BigDecimal outSpeedBit = (BigDecimal) outField.get(obj) == null ? BigDecimal.ZERO : (BigDecimal) outField.get(obj);

                // 累加bit值(用于计算平均值)
                totalInSpeedBit = totalInSpeedBit.add(inSpeedBit);
                totalOutSpeedBit = totalOutSpeedBit.add(outSpeedBit);
            } catch (Exception e) {
                throw new RuntimeException("无法获取速度字段值", e);
            }
        }

        // 计算Gb平均值
        BigDecimal size = new BigDecimal(list.size());
        BigDecimal avgInSpeedGb = totalInSpeedBit.divide(size, 2, RoundingMode.HALF_UP);
        BigDecimal avgOutSpeedGb = totalOutSpeedBit.divide(size, 2, RoundingMode.HALF_UP);

        // 基于平均值的较大值确定推荐单位
        BigDecimal maxAvgBit = avgInSpeedGb.compareTo(avgOutSpeedGb) > 0 ?
                avgInSpeedGb : avgOutSpeedGb;

        String recommendedUnit;
        if (maxAvgBit.compareTo(new BigDecimal("1000000000")) >= 0) {
            recommendedUnit = "Gb";
        } else if (maxAvgBit.compareTo(new BigDecimal("1000000")) >= 0) {
            recommendedUnit = "Mb";
        } else{
            recommendedUnit = "Kb";
        }

        return recommendedUnit;
    }
    /**
     * 计算String类型（存储数字）的速度统计结果
     * @param list 数据列表
     * @param inSpeedField 输入速度字段名
     * @param outSpeedField 输出速度字段名
     * @return SpeedResult 速度统计结果
     */
    public static SpeedResult calculateWithStringTraffic(List<?> list,
                                                         String inSpeedField, String outSpeedField)
            throws NoSuchFieldException, IllegalAccessException {

        if (list == null || list.isEmpty()) {
            return new SpeedResult(
                    BigDecimal.ZERO, BigDecimal.ZERO,
                    BigDecimal.ZERO, BigDecimal.ZERO,
                    BigDecimal.ZERO, BigDecimal.ZERO,
                    "bit"
            );
        }

        BigDecimal totalInSpeedBit = BigDecimal.ZERO;
        BigDecimal totalOutSpeedBit = BigDecimal.ZERO;
        BigDecimal maxInSpeedGb = BigDecimal.ZERO;
        BigDecimal maxOutSpeedGb = BigDecimal.ZERO;
        BigDecimal lastInSpeedGb = BigDecimal.ZERO;
        BigDecimal lastOutSpeedGb = BigDecimal.ZERO;

        final BigDecimal GB_DIVISOR = new BigDecimal("1000000000");

        // 计算总和(bit)和Gb值
        for (Object obj : list) {
            try {
                java.lang.reflect.Field inField = obj.getClass().getDeclaredField(inSpeedField);
                java.lang.reflect.Field outField = obj.getClass().getDeclaredField(outSpeedField);

                inField.setAccessible(true);
                outField.setAccessible(true);

                // 处理String类型的数字值
                String inSpeedStr = (String) inField.get(obj);
                String outSpeedStr = (String) outField.get(obj);

                BigDecimal inSpeedBit = convertStringToBigDecimal(inSpeedStr);
                BigDecimal outSpeedBit = convertStringToBigDecimal(outSpeedStr);

                // 累加bit值(用于计算平均值)
                totalInSpeedBit = totalInSpeedBit.add(inSpeedBit);
                totalOutSpeedBit = totalOutSpeedBit.add(outSpeedBit);

                // 转换为Gb并更新最大值
                BigDecimal inSpeedGb = inSpeedBit.divide(GB_DIVISOR, 2, RoundingMode.HALF_UP);
                BigDecimal outSpeedGb = outSpeedBit.divide(GB_DIVISOR, 2, RoundingMode.HALF_UP);

                maxInSpeedGb = maxInSpeedGb.max(inSpeedGb);
                maxOutSpeedGb = maxOutSpeedGb.max(outSpeedGb);

                // 记录最后一个值
                lastInSpeedGb = inSpeedGb;
                lastOutSpeedGb = outSpeedGb;
            } catch (Exception e) {
                throw new RuntimeException("无法获取或转换速度字段值", e);
            }
        }

        // 计算Gb平均值
        BigDecimal size = new BigDecimal(list.size());
        BigDecimal avgInSpeedGb = totalInSpeedBit.divide(GB_DIVISOR, 2, RoundingMode.HALF_UP)
                .divide(size, 2, RoundingMode.HALF_UP);
        BigDecimal avgOutSpeedGb = totalOutSpeedBit.divide(GB_DIVISOR, 2, RoundingMode.HALF_UP)
                .divide(size, 2, RoundingMode.HALF_UP);

        // 基于平均值的较大值确定推荐单位
        BigDecimal maxAvgBit = avgInSpeedGb.compareTo(avgOutSpeedGb) > 0 ?
                avgInSpeedGb.multiply(GB_DIVISOR) :
                avgOutSpeedGb.multiply(GB_DIVISOR);

        String recommendedUnit;
        if (maxAvgBit.compareTo(new BigDecimal("1000000000")) >= 0) {
            recommendedUnit = "Gb";
        } else if (maxAvgBit.compareTo(new BigDecimal("1000000")) >= 0) {
            recommendedUnit = "Mb";
        } else {
            recommendedUnit = "Kb";
        }

        return new SpeedResult(
                avgInSpeedGb, avgOutSpeedGb,
                maxInSpeedGb, maxOutSpeedGb,
                lastInSpeedGb, lastOutSpeedGb,
                recommendedUnit
        );
    }

    /**
     * 将String类型的数字转换为BigDecimal
     * @param numberStr 数字字符串
     * @return BigDecimal值，转换失败返回0
     */
    private static BigDecimal convertStringToBigDecimal(String numberStr) {
        if (numberStr == null || numberStr.trim().isEmpty()) {
            return BigDecimal.ZERO;
        }

        try {
            return new BigDecimal(numberStr.trim());
        } catch (Exception e) {
            return BigDecimal.ZERO;
        }
    }

    /**
     * 仅计算String类型（存储数字）的推荐单位
     * @param list 数据列表
     * @param inSpeedField 输入速度字段名
     * @param outSpeedField 输出速度字段名
     * @return 推荐单位
     */
    public static String calculateUnitWithStringTraffic(List<?> list,
                                                        String inSpeedField, String outSpeedField)
            throws NoSuchFieldException, IllegalAccessException {

        if (list == null || list.isEmpty()) {
            return null;
        }

        BigDecimal totalInSpeedBit = BigDecimal.ZERO;
        BigDecimal totalOutSpeedBit = BigDecimal.ZERO;

        // 计算总和(bit)
        for (Object obj : list) {
            try {
                java.lang.reflect.Field inField = obj.getClass().getDeclaredField(inSpeedField);
                java.lang.reflect.Field outField = obj.getClass().getDeclaredField(outSpeedField);

                inField.setAccessible(true);
                outField.setAccessible(true);

                // 处理String类型的数字值
                String inSpeedStr = (String) inField.get(obj);
                String outSpeedStr = (String) outField.get(obj);

                BigDecimal inSpeedBit = convertStringToBigDecimal(inSpeedStr);
                BigDecimal outSpeedBit = convertStringToBigDecimal(outSpeedStr);

                totalInSpeedBit = totalInSpeedBit.add(inSpeedBit);
                totalOutSpeedBit = totalOutSpeedBit.add(outSpeedBit);
            } catch (Exception e) {
                throw new RuntimeException("无法获取或转换速度字段值", e);
            }
        }

        // 计算平均值
        BigDecimal size = new BigDecimal(list.size());
        BigDecimal avgInSpeedBit = totalInSpeedBit.divide(size, 2, RoundingMode.HALF_UP);
        BigDecimal avgOutSpeedBit = totalOutSpeedBit.divide(size, 2, RoundingMode.HALF_UP);

        // 基于平均值的较大值确定推荐单位
        BigDecimal maxAvgBit = avgInSpeedBit.compareTo(avgOutSpeedBit) > 0 ?
                avgInSpeedBit : avgOutSpeedBit;

        String recommendedUnit;
        if (maxAvgBit.compareTo(new BigDecimal("1000000000")) >= 0) {
            recommendedUnit = "Gb";
        } else if (maxAvgBit.compareTo(new BigDecimal("1000000")) >= 0) {
            recommendedUnit = "Mb";
        } else {
            recommendedUnit = "Kb";
        }

        return recommendedUnit;
    }

    // Mbit 转 Bit 换算：1 Mbit = 1,000,000 Bit
    public static BigDecimal mbitToBit(BigDecimal mbitValue) {
        if (mbitValue == null) return BigDecimal.ZERO;
        return mbitValue.multiply(new BigDecimal("1000000"));
    }
}