package org.dromara.web.service;

import java.util.HashMap;
import java.util.Map;

public class MetabolicCalculator {

    // 工具方法：活动系数转换
    private static double getActivityFactor(String activityLevel) {
        return switch (activityLevel) {
            case "轻" -> 1.375;
            case "中" -> 1.55;
            case "重" -> 1.725;
            default -> 1.2; // 默认静态
        };
    }

    // 工具方法：格式化结果
    private static Map<String, String> formatResults(double tdeeKcal, double weight) {
        double tdeeKj = tdeeKcal * 4.184;
        double kcalPerKg = tdeeKcal / weight;

        Map<String, String> results = new HashMap<>();
        results.put("kcal/d", String.format("%.2f", tdeeKcal));
        results.put("kJ/d", String.format("%.2f", tdeeKj));
        results.put("kcal/kg*d", String.format("%.2f", kcalPerKg));
        return results;
    }

    /************************ BEE 计算方法 ************************/
    public static Map<String, String> calculateByBEE(
        String gender, int age, double height, double weight,
        String activityLevel, String stressLevel) {

        // 毛德倩公式（中国人群）
        double bee;
        if ("男".equals(gender)) {
            bee = 48.5 * weight + 2954.7;
        } else {
            bee = 41.9 * weight + 2869.1;
        }

        double activityFactor = getActivityFactor(activityLevel);

        // 应激系数转换
        double stressFactor = switch (stressLevel) {
            case "低级" -> 1.1;
            case "中级" -> 1.2;
            case "严重" -> 1.3;
            case "恶性肿瘤" -> 1.4;
            default -> 1.0; // 基础状态
        };

        double tdeeKcal = bee * activityFactor * stressFactor;
        return formatResults(tdeeKcal, weight);
    }

    /************************ DRIS 计算方法 ************************/
    public static Map<String, String> calculateByDRIS(
        String gender, int age, double height, double weight,
        String activityLevel) {

        // 根据年龄和性别确定基础代谢系数
        double baseFactor;
        if (age < 30) {
            baseFactor = "男".equals(gender) ? 38.5 : 35.0;
        } else if (age < 50) {
            baseFactor = "男".equals(gender) ? 36.0 : 33.0;
        } else {
            baseFactor = "男".equals(gender) ? 34.0 : 30.5;
        }

        // 根据活动强度调整
        double activityBonus = switch (activityLevel) {
            case "低" -> 1.0;
            case "中" -> 3.5;
            case "重" -> 7.0;
            default -> 0; // 静态
        };

        double kcalPerKg = baseFactor + activityBonus;
        double tdeeKcal = weight * kcalPerKg;

        return formatResults(tdeeKcal, weight);
    }

    /************************ 拇指测法 ************************/
    public static Map<String, String> calculateByThumb(
        String gender, int age, double height, double weight,
        String activityLevel) {

        // 根据活动水平确定系数范围
        double minFactor, maxFactor;
        switch (activityLevel) {
            case "轻" -> { minFactor = 25; maxFactor = 30; }
            case "中" -> { minFactor = 30; maxFactor = 35; }
            case "重" -> { minFactor = 35; maxFactor = 40; }
            default -> { minFactor = 20; maxFactor = 25; }  // 静态
        }

        // 在范围内取中间值
        double factor = (minFactor + maxFactor) / 2.0;

        // 性别调整（男性通常略高）
        if ("男".equals(gender)) factor *= 1.05;

        // 年龄调整（30岁以下代谢较高）
        if (age < 30) factor *= 1.08;

        double tdeeKcal = weight * factor;

        return formatResults(tdeeKcal, weight);
    }

    /************************ 烧伤公式 ************************/
    public static Map<String, String> calculateByBurnFormula(
        String gender, int age, double height, double weight,
        String activityLevel, double burnAreaPercent) {

        // 基于Harris-Benedict公式计算基础代谢
        double bee;
        if ("男".equals(gender)) {
            bee = 66.5 + (13.75 * weight) + (5.003 * height) - (6.775 * age);
        } else {
            bee = 655.1 + (9.563 * weight) + (1.850 * height) - (4.676 * age);
        }

        // 活动系数
        double activityFactor = getActivityFactor(activityLevel);

        // Curreri公式：基础代谢 + 烧伤增量
        double burnCalories = 40 * burnAreaPercent;
        double tdeeKcal = (bee + burnCalories) * activityFactor;

        return formatResults(tdeeKcal, weight);
    }

    /************************ 测试方法 ************************/
    public static void main(String[] args) {
        // BEE测试用例: 35岁男性,175cm,70kg,中度活动,低级应激
        System.out.println("BEE计算方法:");
        Map<String, String> beeResult = calculateByBEE("男", 35, 175, 70, "中", "低级");
        beeResult.forEach((k, v) -> System.out.println(k + ": " + v));

        // DRIS测试用例: 30岁女性,165cm,60kg,中度活动
        System.out.println("\nDRIS计算方法:");
        Map<String, String> drisResult = calculateByDRIS("女", 30, 165, 60, "中");
        drisResult.forEach((k, v) -> System.out.println(k + ": " + v));

        // 拇指测法测试用例: 25岁男性,180cm,80kg,重度活动
        System.out.println("\n拇指测法:");
        Map<String, String> thumbResult = calculateByThumb("男", 25, 180, 80, "重");
        thumbResult.forEach((k, v) -> System.out.println(k + ": " + v));

        // 烧伤公式测试用例: 40岁女性,160cm,55kg,轻度活动,烧伤面积30%
        System.out.println("\n烧伤公式:");
        Map<String, String> burnResult = calculateByBurnFormula("女", 40, 160, 55, "轻", 30.0);
        burnResult.forEach((k, v) -> System.out.println(k + ": " + v));
    }
}
