60 lines
1.9 KiB
C#
60 lines
1.9 KiB
C#
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);
|
|
}
|
|
}
|