import type { DayMealsByType, Ingredient, Meal, MealItem, NutritionTotals, } from '@/types/domain' const round2 = (value: number): number => Math.round(value * 100) / 100 export const emptyTotals = (): NutritionTotals => ({ protein_g: 0, carbs_g: 0, sugar_g: 0, fat_g: 0, fiber_g: 0, kcal: 0, }) export const computeItemNutrition = (ingredient: Ingredient, grams: number): NutritionTotals => { const factor = grams / 100 const protein = round2(ingredient.protein_g_100 * factor) const carbs = round2(ingredient.carbs_g_100 * factor) const sugar = round2(ingredient.sugar_g_100 * factor) const fat = round2(ingredient.fat_g_100 * factor) const fiber = round2(ingredient.fiber_g_100 * factor) const kcal = round2(protein * 4 + carbs * 4 + fat * 9) return { protein_g: protein, carbs_g: carbs, sugar_g: sugar, fat_g: fat, fiber_g: fiber, kcal, } } export const addTotals = (base: NutritionTotals, add: NutritionTotals): NutritionTotals => { return { protein_g: round2(base.protein_g + add.protein_g), carbs_g: round2(base.carbs_g + add.carbs_g), sugar_g: round2(base.sugar_g + add.sugar_g), fat_g: round2(base.fat_g + add.fat_g), fiber_g: round2(base.fiber_g + add.fiber_g), kcal: round2(base.kcal + add.kcal), } } export const computeMealTotals = (items: MealItem[]): NutritionTotals => { let totals = emptyTotals() for (const item of items) { if (!item.ingredient || item.grams <= 0) { continue } const itemTotals = computeItemNutrition(item.ingredient, item.grams) totals = addTotals(totals, itemTotals) } return totals } export const computeDayTotals = (mealsByType: Partial): NutritionTotals => { let totals = emptyTotals() for (const meal of Object.values(mealsByType)) { if (!meal) { continue } const mealTotals = computeMealTotals(meal.items ?? []) totals = addTotals(totals, mealTotals) } return totals } export const withComputedMealTotals = (meal: Meal): Meal => { return { ...meal, totals: computeMealTotals(meal.items ?? []), } }