namespace MealPlan.Api.Services.Generators; public static class TdeeCalculator { public record MacroTargets(int Calories, decimal ProteinG, decimal FatG, decimal CarbsG, string Rationale); public static MacroTargets Calculate( decimal heightCm, decimal weightKg, int age, string sex, string activityLevel, string goal) { var bmr = sex.ToLowerInvariant() switch { "female" => 10m * weightKg + 6.25m * heightCm - 5m * age - 161m, _ => 10m * weightKg + 6.25m * heightCm - 5m * age + 5m, }; var multiplier = activityLevel.ToLowerInvariant() switch { "sedentary" => 1.2m, "light" => 1.375m, "moderate" => 1.55m, "active" => 1.725m, "very_active" => 1.9m, _ => 1.55m, }; var tdee = bmr * multiplier; var adjustment = goal.ToLowerInvariant() switch { "lose_weight" => -500, "gain_muscle" => 300, "recomp" => -200, _ => 0, }; var calories = Math.Max(1200, (int)Math.Round(tdee + adjustment)); var (proteinPct, fatPct, carbsPct) = goal.ToLowerInvariant() switch { "gain_muscle" => (0.30m, 0.25m, 0.45m), "lose_weight" => (0.35m, 0.25m, 0.40m), "recomp" => (0.32m, 0.28m, 0.40m), _ => (0.25m, 0.30m, 0.45m), }; var proteinG = Math.Round(calories * proteinPct / 4m, 1); var fatG = Math.Round(calories * fatPct / 9m, 1); var carbsG = Math.Round(calories * carbsPct / 4m, 1); var rationale = $"TDEE ≈ {(int)Math.Round(tdee)} kcal ({activityLevel}, {goal}). Target {calories} kcal after goal adjustment."; return new MacroTargets(calories, proteinG, fatG, carbsG, rationale); } }