initial logic, just gotta get ingredients and recipes right now

This commit is contained in:
Diogo Peralta Cordeiro 2025-01-03 16:47:52 +00:00
commit 20133867f3
Signed by: diogo
GPG Key ID: 18D2D35001FBFAB0

470
index.php Normal file
View File

@ -0,0 +1,470 @@
<!DOCTYPE html>
<HTML>
<HEAD>
<META name="robots" content="noindex, nofollow" />
<META http-equiv="Content-type" content="text/html;charset=UTF-8" />
<meta charset="utf-8">
<META http-equiv="cache-control" content="no-cache" />
<META http-equiv="expires" content="0" />
<META http-equiv="pragma" content="no-cache" />
<META name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<TITLE>Plano Mensal de Dieta e Lista de Compras</TITLE>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=PT+Sans:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet">
<LINK rel="stylesheet" href="https://diogo.site/assets/css/main.css" />
<STYLE>
P {
text-align: justify;
}
form, input, textarea, button, select {
font-family: inherit;
font-weight: inherit;
font-size: inherit;
}
form {
margin-bottom: 15px;
}
label {
font-weight: bold;
}
input[type="text"],
input[type="email"],
textarea {
width: 100%;
padding: 0.5em;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
button[type="submit"] {
background-color: #1A936F;
color: white;
padding: 0.5em 1em;
border: none;
border-radius: 4px;
cursor: pointer;
margin: 0.3em;
}
button[type="submit"]:hover {
background-color: #22be90;
}
.plate {
border: 1px dotted rgba(0, 0, 0, 0.2);
padding: 10px;
margin: 10px 0;
}
.plate p{
margin-bottom: 0.5rem;
}
.plateDetails {
color: #9cadc7;
}
</STYLE>
</HEAD>
<BODY>
<form method="get">
<label for="include_weekends">Incluir fim-de-semana:
<input type="checkbox" name="include_weekends" id="include_weekends" <?php echo isset($_GET['include_weekends']) ? 'checked' : ''; ?>>
</label>
<br>
<label for="is_female">Sexo:</label>
<select name="is_female" id="is_female">
<option value="false" <?php echo isset($_GET['is_female']) && $_GET['is_female'] == 'false' ? 'selected' : ''; ?>>Masculino</option>
<option value="true" <?php echo isset($_GET['is_female']) && $_GET['is_female'] == 'true' ? 'selected' : ''; ?>>Feminino</option>
</select>
<br>
<label for="weight">Peso (kg):</label>
<input type="number" step="0.1" name="weight" id="weight" value="<?php echo isset($_GET['weight']) ? $_GET['weight'] : ''; ?>" required>
<br>
<label for="height">Altura (cm):</label>
<input type="number" step="0.1" name="height" id="height" value="<?php echo isset($_GET['height']) ? $_GET['height'] : ''; ?>" required>
<br>
<label for="age">Idade:</label>
<input type="number" name="age" id="age" value="<?php echo isset($_GET['age']) ? $_GET['age'] : ''; ?>" required>
<br>
<label for="activity_level">Nível de atividade:</label>
<select name="activity_level" id="activity_level">
<option value="1.2" <?php echo isset($_GET['activity_level']) && $_GET['activity_level'] == '1.2' ? 'selected' : ''; ?>>Sedentário (pouco ou nenhum exercício)</option>
<option value="1.55" <?php echo isset($_GET['activity_level']) && $_GET['activity_level'] == '1.55' ? 'selected' : ''; ?>>Atividade moderada (exercício moderado)</option>
<option value="1.9" <?php echo isset($_GET['activity_level']) && $_GET['activity_level'] == '1.9' ? 'selected' : ''; ?>>Atividade intensa (exercício intenso)</option>
</select>
<br>
<button type="submit">Gerar plano alimentar</button>
<button type="submit" name="rand">Forçar uma nova ementa</button>
</form>
<?php
if (!isset($_GET["rand"])) {
$currentMonth = date('n');
mt_srand($currentMonth);
}
$mealOptionsAndIngredients = [
'Brunch' => [
'Vegetarian' => [
'Batido de iogurte grego, aveia, e frutos vermelhos congelados' => ['iogurte grego', 'aveia', 'frutos vermelhos congelados'],
'Torrada integral com abacate e ovos mexidos' => ['pão integral', 'abacate', 'ovos'],
'Omelete de espinafres e tomate com pão integral' => ['ovos', 'espinafres', 'tomate', 'pão integral'],
'Papas de aveia com mel e frutos vermelhos congelados' => ['aveia', 'mel', 'frutos vermelhos congelados'],
'Batido de whey protein, aveia e frutos vermelhos congelados' => ['whey protein', 'aveia', 'frutos vermelhos congelados'],
'Batido de whey protein com banana e leite' => ['whey protein', 'banana', 'leite'],
],
],
'Lunch' => [
'Poultry' => [
'Hambúrguer de peru com batatas-doce assada e salada' => ['carne de peru', 'batatas-doce', 'salada'],
'Wrap de frango com abacate e legumes' => ['tortilla integral', 'frango', 'abacate', 'legumes'],
'Peito de frango grelhado com quinoa e espinafres' => ['peito de frango', 'quinoa', 'espinafres'],
'Wrap de peru com húmus e legumes' => ['peru', 'húmus', 'wraps', 'legumes'],
],
'Fish' => [
'Filetes de peixe branco com puré de batatas e feijão-verde' => ['filetes de peixe branco', 'batatas', 'feijão-verde'],
'Salmão grelhado com puré de batatas e brócolos' => ['salmão', 'batatas', 'brócolos'],
],
'Vegetarian' => [
'Tofu salteado com pimentos e quinoa' => ['tofu', 'pimentos', 'quinoa'],
],
],
'Snack' => [
'Vegetarian' => [
'Iogurte grego com frutos vermelhos congelados' => ['iogurte grego', 'frutos vermelhos congelados'],
'Queijo cottage com mel e frutos secos' => ['queijo cottage', 'mel', 'frutos secos'],
'Ovos cozidos com uvas' => ['ovos', 'uvas'],
'Iogurte grego com granola baixa em açúcar' => ['iogurte grego', 'granola baixa em açúcar'],
'Queijo cottage com uvas' => ['queijo cottage', 'uvas'],
],
],
'PreWorkout' => [
'Vegetarian' => [
'Barra de proteína (baixo em açúcar)' => ['barra de proteína'],
'Tortitas de arroz com mel ou manteiga de amendoim e uma maçã' => ['tortitas de arroz', 'mel', 'manteiga de amendoim', 'maçã'],
'Um punhado de frutos secos e uma banana' => ['frutos secos', 'banana'],
],
],
'Dinner' => [
'Fish' => [
'Salmão grelhado com batatas-doce e feijão-verde' => ['salmão', 'batatas-doce', 'feijão-verde'],
'Peixe grelhado com legumes salteados' => ['peixe branco', 'legumes'],
],
'Meat' => [
'Salteado de carne de vaca magra com arroz e legumes' => ['carne de vaca magra', 'arroz', 'legumes'],
'Carne picada de vaca com quinoa e pimentos' => ['carne picada de vaca', 'quinoa', 'pimentos'],
],
'Vegetarian' => [
'Tofu salteado com pimentos e quinoa' => ['tofu', 'pimentos', 'quinoa'],
],
],
];
$ingredientNutrition = [
'abacate' => ['calories' => 160, 'protein' => 2, 'fat' => 15, 'carbs' => 9, 'portion' => 100, 'unit' => 'g'],
'abóbora' => ['calories' => 26, 'protein' => 1, 'fat' => 0, 'carbs' => 7, 'portion' => 100, 'unit' => 'g'],
'alface' => ['calories' => 15, 'protein' => 1, 'fat' => 0, 'carbs' => 3, 'portion' => 100, 'unit' => 'g'],
'alho' => ['calories' => 149, 'protein' => 6, 'fat' => 0, 'carbs' => 33, 'portion' => 100, 'unit' => 'g'],
'amêndoas' => ['calories' => 576, 'protein' => 21, 'fat' => 49, 'carbs' => 22, 'portion' => 100, 'unit' => 'g'],
'arroz' => ['calories' => 130, 'protein' => 2, 'fat' => 0, 'carbs' => 28, 'portion' => 100, 'unit' => 'g (cooked)'],
'arroz integral' => ['calories' => 111, 'protein' => 3, 'fat' => 1, 'carbs' => 23, 'portion' => 100, 'unit' => 'g (cooked)'],
'aveia' => ['calories' => 150, 'protein' => 5, 'fat' => 3, 'carbs' => 27, 'portion' => 50, 'unit' => 'g'],
'azeite' => ['calories' => 119, 'protein' => 0, 'fat' => 14, 'carbs' => 0, 'portion' => 10, 'unit' => 'g'],
'bacon' => ['calories' => 42, 'protein' => 3, 'fat' => 3, 'carbs' => 0, 'portion' => 50, 'unit' => 'g'],
'banana' => ['calories' => 89, 'protein' => 1, 'fat' => 0, 'carbs' => 23, 'portion' => 1, 'unit' => ''],
'barra de proteína' => ['calories' => 200, 'protein' => 20, 'fat' => 6, 'carbs' => 18, 'portion' => 1, 'unit' => ''],
'batatas' => ['calories' => 77, 'protein' => 2, 'fat' => 0, 'carbs' => 17, 'portion' => 100, 'unit' => 'g'],
'batatas-doce' => ['calories' => 86, 'protein' => 2, 'fat' => 0, 'carbs' => 20, 'portion' => 100, 'unit' => 'g'],
'bife' => ['calories' => 250, 'protein' => 26, 'fat' => 17, 'carbs' => 0, 'portion' => 100, 'unit' => 'g'],
'brócolos' => ['calories' => 55, 'protein' => 3, 'fat' => 1, 'carbs' => 11, 'portion' => 100, 'unit' => 'g'],
'carne de peru' => ['calories' => 140, 'protein' => 22, 'fat' => 6, 'carbs' => 0, 'portion' => 100, 'unit' => 'g'],
'carne de vaca magra' => ['calories' => 143, 'protein' => 20, 'fat' => 6, 'carbs' => 0, 'portion' => 100, 'unit' => 'g'],
'carne picada de vaca' => ['calories' => 250, 'protein' => 20, 'fat' => 18, 'carbs' => 0, 'portion' => 100, 'unit' => 'g'],
'cebola' => ['calories' => 40, 'protein' => 1, 'fat' => 0, 'carbs' => 9, 'portion' => 100, 'unit' => 'g'],
'cogumelos' => ['calories' => 22, 'protein' => 3, 'fat' => 0, 'carbs' => 3, 'portion' => 100, 'unit' => 'g'],
'courgette' => ['calories' => 17, 'protein' => 1, 'fat' => 0, 'carbs' => 3, 'portion' => 100, 'unit' => 'g'],
'couve-flor' => ['calories' => 25, 'protein' => 2, 'fat' => 0, 'carbs' => 5, 'portion' => 100, 'unit' => 'g'],
'creme de leite' => ['calories' => 300, 'protein' => 2, 'fat' => 30, 'carbs' => 4, 'portion' => 30, 'unit' => 'g'],
'espinafres' => ['calories' => 23, 'protein' => 3, 'fat' => 0, 'carbs' => 4, 'portion' => 100, 'unit' => 'g'],
'feijão' => ['calories' => 127, 'protein' => 8, 'fat' => 0, 'carbs' => 23, 'portion' => 100, 'unit' => 'g (cooked)'],
'feijão-verde' => ['calories' => 31, 'protein' => 2, 'fat' => 0, 'carbs' => 7, 'portion' => 100, 'unit' => 'g'],
'filete de peixe' => ['calories' => 120, 'protein' => 20, 'fat' => 4, 'carbs' => 0, 'portion' => 100, 'unit' => 'g'],
'filetes de peixe branco' => ['calories' => 105, 'protein' => 22, 'fat' => 2, 'carbs' => 0, 'portion' => 100, 'unit' => 'g'],
'frango' => ['calories' => 165, 'protein' => 31, 'fat' => 4, 'carbs' => 0, 'portion' => 100, 'unit' => 'g'],
'frutos secos' => ['calories' => 607, 'protein' => 15, 'fat' => 56, 'carbs' => 20, 'portion' => 100, 'unit' => 'g'],
'frutos vermelhos congelados' => ['calories' => 50, 'protein' => 1, 'fat' => 0, 'carbs' => 12, 'portion' => 100, 'unit' => 'g'],
'granola baixa em açúcar' => ['calories' => 200, 'protein' => 4, 'fat' => 7, 'carbs' => 33, 'portion' => 50, 'unit' => 'g'],
'grão-de-bico' => ['calories' => 164, 'protein' => 9, 'fat' => 3, 'carbs' => 27, 'portion' => 100, 'unit' => 'g (cooked)'],
'húmus' => ['calories' => 166, 'protein' => 8, 'fat' => 10, 'carbs' => 14, 'portion' => 100, 'unit' => 'g'],
'iogurte grego' => ['calories' => 60, 'protein' => 10, 'fat' => 2, 'carbs' => 3, 'portion' => 100, 'unit' => 'g'],
'legumes' => ['calories' => 50, 'protein' => 2, 'fat' => 0, 'carbs' => 10, 'portion' => 100, 'unit' => 'g'],
'leite' => ['calories' => 42, 'protein' => 3, 'fat' => 1, 'carbs' => 5, 'portion' => 200, 'unit' => 'ml'],
'leite de amêndoas' => ['calories' => 13, 'protein' => 0, 'fat' => 1, 'carbs' => 1, 'portion' => 200, 'unit' => 'ml'],
'leite de soja' => ['calories' => 43, 'protein' => 4, 'fat' => 2, 'carbs' => 2, 'portion' => 200, 'unit' => 'ml'],
'lentilhas' => ['calories' => 116, 'protein' => 9, 'fat' => 0, 'carbs' => 20, 'portion' => 100, 'unit' => 'g (cooked)'],
'maçã' => ['calories' => 52, 'protein' => 0, 'fat' => 0, 'carbs' => 14, 'portion' => 1, 'unit' => ''],
'manteiga' => ['calories' => 717, 'protein' => 1, 'fat' => 81, 'carbs' => 1, 'portion' => 15, 'unit' => 'g'],
'manteiga de amendoim' => ['calories' => 94, 'protein' => 4, 'fat' => 8, 'carbs' => 3, 'portion' => 1, 'unit' => 'tbsp'],
'massa' => ['calories' => 131, 'protein' => 5, 'fat' => 1, 'carbs' => 26, 'portion' => 100, 'unit' => 'g (cooked)'],
'mel' => ['calories' => 64, 'protein' => 0, 'fat' => 0, 'carbs' => 17, 'portion' => 1, 'unit' => 'tbsp'],
'nozes' => ['calories' => 654, 'protein' => 15, 'fat' => 65, 'carbs' => 14, 'portion' => 100, 'unit' => 'g'],
'ovos' => ['calories' => 70, 'protein' => 6, 'fat' => 5, 'carbs' => 1, 'portion' => 1, 'unit' => ''],
'pão integral' => ['calories' => 70, 'protein' => 3, 'fat' => 1, 'carbs' => 14, 'portion' => 1, 'unit' => 'slice'],
'peito de frango' => ['calories' => 165, 'protein' => 31, 'fat' => 4, 'carbs' => 0, 'portion' => 100, 'unit' => 'g'],
'peixe branco' => ['calories' => 120, 'protein' => 20, 'fat' => 4, 'carbs' => 0, 'portion' => 100, 'unit' => 'g'],
'pepino' => ['calories' => 16, 'protein' => 1, 'fat' => 0, 'carbs' => 4, 'portion' => 100, 'unit' => 'g'],
'pimentos' => ['calories' => 20, 'protein' => 1, 'fat' => 0, 'carbs' => 5, 'portion' => 100, 'unit' => 'g'],
'queijo cottage' => ['calories' => 98, 'protein' => 11, 'fat' => 4, 'carbs' => 3, 'portion' => 100, 'unit' => 'g'],
'queijo feta' => ['calories' => 264, 'protein' => 14, 'fat' => 21, 'carbs' => 4, 'portion' => 100, 'unit' => 'g'],
'quinoa' => ['calories' => 120, 'protein' => 4, 'fat' => 2, 'carbs' => 21, 'portion' => 100, 'unit' => 'g (cooked)'],
'salada' => ['calories' => 15, 'protein' => 1, 'fat' => 0, 'carbs' => 3, 'portion' => 100, 'unit' => 'g'],
'salmão' => ['calories' => 206, 'protein' => 22, 'fat' => 13, 'carbs' => 0, 'portion' => 100, 'unit' => 'g'],
'sementes de abóbora' => ['calories' => 446, 'protein' => 19, 'fat' => 19, 'carbs' => 54, 'portion' => 100, 'unit' => 'g'],
'sementes de chia' => ['calories' => 486, 'protein' => 17, 'fat' => 31, 'carbs' => 42, 'portion' => 100, 'unit' => 'g'],
'temperos' => ['calories' => 5, 'protein' => 0, 'fat' => 0, 'carbs' => 1, 'portion' => 5, 'unit' => 'g'],
'tofu' => ['calories' => 94, 'protein' => 10, 'fat' => 5, 'carbs' => 2, 'portion' => 100, 'unit' => 'g'],
'tomate' => ['calories' => 18, 'protein' => 1, 'fat' => 0, 'carbs' => 4, 'portion' => 100, 'unit' => 'g'],
'tomate seco' => ['calories' => 258, 'protein' => 9, 'fat' => 11, 'carbs' => 35, 'portion' => 50, 'unit' => 'g'],
'tortitas de arroz' => ['calories' => 35, 'protein' => 1, 'fat' => 0, 'carbs' => 7, 'portion' => 1, 'unit' => ''],
'uvas' => ['calories' => 67, 'protein' => 1, 'fat' => 0, 'carbs' => 17, 'portion' => 100, 'unit' => 'g'],
'whey protein' => ['calories' => 120, 'protein' => 25, 'fat' => 1, 'carbs' => 2, 'portion' => 1, 'unit' => 'scoop'],
'wraps' => ['calories' => 150, 'protein' => 5, 'fat' => 4, 'carbs' => 25, 'portion' => 1, 'unit' => ''],
];
// https://en.wikipedia.org/wiki/Harris%E2%80%93Benedict_equation
// https://www.nutritioncarepro.com/harris-benedict-equation
// https://www.k-state.edu/paccats/Contents/PA/PDF/Physical%20Activity%20and%20Controlling%20Weight.pdf
// https://www.healthline.com/health/what-is-basal-metabolic-rate#takeaway
function calculateBMR($is_female, $weight, $height, $age, $activity_level) {
if ($is_female)
$bmr = (9.5634 * $weight) + (1.8496 * $height) - (4.6756 * $age) + 655.0955;
else
$bmr = (13.7516 * $weight) + (5.0033 * $height) - (6.755 * $age) + 66.473;
return $bmr * $activity_level;
}
function calculateMealNutrition($ingredients, $nutritionData, $scaleFactors = []) {
$total = ['calories' => 0, 'protein' => 0, 'fat' => 0, 'carbs' => 0];
$ingredientPortions = []; // To track the portions for the shopping list
foreach ($ingredients as $ingredient) {
if (isset($nutritionData[$ingredient])) {
$scale = $scaleFactors[$ingredient] ?? 1;
foreach ($total as $key => $value) {
$total[$key] += $nutritionData[$ingredient][$key] * $scale;
}
// Track the portion of each ingredient
$ingredientPortions[$ingredient] = ($ingredientPortions[$ingredient] ?? 0) + $scale;
}
}
return ['nutrition' => $total, 'portions' => $ingredientPortions];
}
function getBalancedMeal($mealType, &$selectedMeals, $nutritionData, &$remainingGoals) {
global $mealOptionsAndIngredients;
if (!isset($mealOptionsAndIngredients[$mealType])) {
return ["Base de Dados vazia :s", [], ['calories' => 0, 'protein' => 0, 'fat' => 0, 'carbs' => 0], []];
}
$categories = array_keys($mealOptionsAndIngredients[$mealType]);
shuffle($categories); // Shuffle categories for randomness
foreach ($categories as $category) {
$availableMeals = array_filter(
$mealOptionsAndIngredients[$mealType][$category],
function ($meal) use ($selectedMeals, $mealType) {
return !in_array($meal, $selectedMeals[$mealType]); // Exclude already selected meals
}
);
// If no meals are available, consider all meals in the category
if (empty($availableMeals)) {
$availableMeals = $mealOptionsAndIngredients[$mealType][$category];
// Reset selection of this type
$selectedMeals[$mealType] = [];
}
foreach ($availableMeals as $mealName => $ingredients) {
$scaleFactors = [];
$totalCalories = 0;
$totalProtein = 0;
$totalFat = 0;
$totalCarbs = 0;
// Calculate total nutritional values for the meal
foreach ($ingredients as $ingredient) {
if (isset($nutritionData[$ingredient])) {
$totalCalories += $nutritionData[$ingredient]['calories'];
$totalProtein += $nutritionData[$ingredient]['protein'];
$totalFat += $nutritionData[$ingredient]['fat'];
$totalCarbs += $nutritionData[$ingredient]['carbs'];
}
}
// Calculate scale factors based on remaining goals
$scaleCalories = $totalCalories > 0 ? $remainingGoals['calories'] / $totalCalories : 1;
$scaleProtein = $totalProtein > 0 ? $remainingGoals['protein'] / $totalProtein : 1;
$scaleFat = $totalFat > 0 ? $remainingGoals['fat'] / $totalFat : 1;
$scaleCarbs = $totalCarbs > 0 ? $remainingGoals['carbs'] / $totalCarbs : 1;
// Scale the meal to fit the remaining nutritional goals
$scale = min($scaleCalories, $scaleProtein, $scaleFat, $scaleCarbs);
// If a valid scale is found, calculate the nutrition
if ($scale > 0) {
$mealNutrition = calculateMealNutrition($ingredients, $nutritionData, array_fill_keys(array_keys($ingredients), $scale));
$nutrition = $mealNutrition['nutrition'];
$portions = $mealNutrition['portions'];
// Ensure the meal fits within the remaining goals
if (
$nutrition['calories'] <= $remainingGoals['calories'] &&
$nutrition['protein'] <= $remainingGoals['protein'] &&
$nutrition['fat'] <= $remainingGoals['fat'] &&
$nutrition['carbs'] <= $remainingGoals['carbs']
) {
$selectedMeals[$mealType] []= $mealName;
foreach ($remainingGoals as $key => &$value) {
$value -= $nutrition[$key]; // Update remaining goals
}
unset($value); // Clean up reference
return [$mealName, $ingredients, $nutrition, $portions];
}
}
}
}
return ["Já comeste o suficiente, agora passa fome!", [], ['calories' => 0, 'protein' => 0, 'fat' => 0, 'carbs' => 0], []];
}
function getWeeksOfCurrentMonth() {
$currentDate = new DateTime();
$currentDate->modify('first day of this month');
$startOfMonth = $currentDate->format('Y-m-d');
$endOfMonth = $currentDate->modify('last day of this month')->format('Y-m-d');
$weeks = [];
$currentWeekStart = new DateTime($startOfMonth);
while ($currentWeekStart->format('Y-m-d') <= $endOfMonth) {
$weekStart = clone $currentWeekStart;
$weekEnd = clone $currentWeekStart;
$weekEnd->modify('next Sunday');
if ($weekEnd->format('Y-m-d') > $endOfMonth) {
$weekEnd = new DateTime($endOfMonth);
}
$weeks[] = [
'week_start' => $weekStart->format('Y-m-d'),
'week_end' => $weekEnd->format('Y-m-d'),
];
$currentWeekStart->modify('next Monday');
}
return $weeks;
}
function generateMonthPlan($includeWeekends, $is_female, $weight, $height, $age, $activity_level) {
global $ingredientNutrition, $mealOptionsAndIngredients;
$bmr = calculateBMR($is_female, $weight, $height, $age, $activity_level);
// https://www.healthline.com/nutrition/best-macronutrient-ratio
// These ranges are recommended by the Institute of Medicine and are widely accepted in nutritional science.
// https://www.nal.usda.gov/programs/fnic
// Carbohydrates provide 4 calories per gram,
// protein provides 4 calories per gram,
// and fat provides 9 calories per gram.
$dailyMacronutrientGoals = [
'calories' => round($bmr),
'protein' => round($bmr * 0.3 / 4), // "10-35% from protein"
'fat' => round($bmr * 0.25 / 9), // "20-35% from fats"
'carbs' => round($bmr * 0.45 / 4), // "45-65% of your daily calories from carbs"
];
$weeks = getWeeksOfCurrentMonth();
$usedIngredients = [];
$plan = "<h1>Plano Alimentar do Mês</h1>\n";
$plan .= "<h2>Meta Diária de Macronutrientes:</h2>\n";
$plan .= "<ul><li>Calorias: {$dailyMacronutrientGoals['calories']} kcal</li>";
$plan .= "<li>Proteína: {$dailyMacronutrientGoals['protein']}g</li>";
$plan .= "<li>Gordura: {$dailyMacronutrientGoals['fat']}g</li>";
$plan .= "<li>Carboidratos: {$dailyMacronutrientGoals['carbs']}g</li></ul>";
foreach ($weeks as $week) {
$plan .= "<h2>Semana de {$week['week_start']} a {$week['week_end']}</h2>\n";
$daysOfWeek = $includeWeekends
? ['Segunda-feira', 'Terça-feira', 'Quarta-feira', 'Quinta-feira', 'Sexta-feira', 'Sábado', 'Domingo']
: ['Segunda-feira', 'Terça-feira', 'Quarta-feira', 'Quinta-feira', 'Sexta-feira'];
$selectedMeals = ['Brunch' => [], 'Lunch' => [], 'Snack' => [], 'PreWorkout' => [], 'Dinner' => []]; // Reset weekly meal selection
foreach ($daysOfWeek as $day) {
$plan .= "<h3>{$day}</h3>\n";
$remainingGoals = $dailyMacronutrientGoals; // Use daily goals for each day
$mealtypeToPortuguese = ['Brunch' => 'Pequeno-almoço', 'Lunch' => 'Almoço', 'Snack' => 'Lanche', 'PreWorkout' => 'Pré-treino', 'Dinner' => 'Jantar'];
foreach (['Brunch', 'Lunch', 'Snack', 'PreWorkout', 'Dinner'] as $mealType) {
list($meal, $ingredients, $nutrition, $portions) = getBalancedMeal($mealType, $selectedMeals, $ingredientNutrition, $remainingGoals);
$plan .= "<div class=\"plate\"><p><strong>{$mealtypeToPortuguese[$mealType]}:</strong> {$meal}</p>\n";
// Display ingredients and their portions
$plan .= "<span class=\"plateDetails\"><p><strong>Ingredientes:</strong> ";
$ingredientList = [];
foreach ($ingredients as $ingredient) {
$gramsRequired = $portions[$ingredient] * $ingredientNutrition[$ingredient]['portion'];
$ingredientList[] = "{$ingredient} ({$gramsRequired} {$ingredientNutrition[$ingredient]['unit']})";
}
$plan .= implode(", ", $ingredientList) . "</p>\n";
$plan .= "<p><strong>Informação Nutricional:</strong> {$nutrition['calories']} kcal, {$nutrition['protein']}g protein, "
. "{$nutrition['fat']}g fat, {$nutrition['carbs']}g carbs</p></span></div>\n";
$usedIngredients = array_merge($usedIngredients, $ingredients);
// Accumulate portions for each ingredient
foreach ($portions as $ingredient => $portion) {
$ingredientPortions[$ingredient] = ($ingredientPortions[$ingredient] ?? 0) + $portion;
}
}
}
}
// Generate shopping list based on the portions and serving sizes (grams)
$usedIngredients = array_unique(array_merge($usedIngredients, array_keys($ingredientPortions)));
sort($usedIngredients);
$plan .= "<h1>Lista de Compras do Mês</h1><ul>\n";
foreach ($usedIngredients as $ingredient) {
$totalPortions = round($ingredientPortions[$ingredient], 2); // Total servings for the month
// Convert servings to grams using the serving size
$gramsRequired = $totalPortions * $ingredientNutrition[$ingredient]['portion'];
$plan .= "<li>{$ingredient}: {$gramsRequired} {$ingredientNutrition[$ingredient]['unit']}</li>\n";
}
$plan .= "</ul>\n";
return $plan;
}
// Check if all required GET parameters are set
if ($_SERVER['REQUEST_METHOD'] != 'GET' || !isset($_GET['is_female'], $_GET['weight'], $_GET['height'], $_GET['age'], $_GET['activity_level'])) {
echo "O plano será gerado assim que preencheres o formulário.";
exit;
} else {
// Process parameters
$includeWeekends = ($_GET['include_weekends'] == "on") ? true : false;
$is_female = ($_GET['is_female'] == "true");
$weight = (float) $_GET['weight'];
$height = (int) $_GET['height'];
$age = (int) $_GET['age'];
$activity_level = (float) $_GET['activity_level'];
echo generateMonthPlan($includeWeekends, $is_female, $weight, $height, $age, $activity_level);
}