import type { NutritionValues, Unit } from "@app/shared-types";
import { computeItemNutrition, roundNutrition, scaleNutrition, sumNutrition } from "./calc.js";
import type { IngredientUnitInfo } from "./units.js";
import type { NutritionDeclaration } from "@app/shared-types";

export interface RecipeIngredientForCalc {
  canonicalIngredientId: string;
  quantity: number;
  unit: Unit;
  optional?: boolean;
}

export interface IngredientNutritionSource extends IngredientUnitInfo {
  nutritionPer100: NutritionDeclaration;
}

export interface RecipeNutritionResult {
  perPortion: NutritionValues;
  total: NutritionValues;
  /** Ingredienser som inte kunde beräknas (saknad densitet etc.) – redovisas öppet. */
  uncomputableIngredientIds: string[];
}

/**
 * Beräkna ett recepts näringsvärden ur dess ingredienser – deterministiskt.
 * Valfria ingredienser exkluderas ur grundberäkningen.
 */
export function computeRecipeNutrition(
  ingredients: RecipeIngredientForCalc[],
  portions: number,
  sources: Map<string, IngredientNutritionSource>,
): RecipeNutritionResult {
  const parts: NutritionValues[] = [];
  const uncomputable: string[] = [];
  for (const ing of ingredients) {
    if (ing.optional) continue;
    const source = sources.get(ing.canonicalIngredientId);
    if (!source) {
      uncomputable.push(ing.canonicalIngredientId);
      continue;
    }
    const values = computeItemNutrition(ing.quantity, ing.unit, source.nutritionPer100, source);
    if (values == null) {
      uncomputable.push(ing.canonicalIngredientId);
      continue;
    }
    parts.push(values);
  }
  const total = sumNutrition(parts);
  const perPortion =
    portions > 0 ? roundNutrition(scaleNutrition(total, 1 / portions)) : roundNutrition(total);
  return { perPortion, total: roundNutrition(total), uncomputableIngredientIds: uncomputable };
}
