import type { IngredientNutritionItem } from "@/types/ingredient-catalog.types";

export interface MacroTotals {
  calories: number;
  protein: number;
  fat: number;
  carbs: number;
}

export interface MacroIngredientInput {
  catalogItemId?: number | null;
  amountGrams?: number | null;
  unit?: string | null;
  name?: string;
}

export function hasNonMacroUnit(unit?: string | null): boolean {
  if (!unit?.trim()) return false;
  const u = unit.trim().toLowerCase();
  return u === "do smaku" || u === "optional" || u === "opcjonalnie" || u === "szczypta";
}

export function shouldIncludeIngredientInMacroSum(ing: MacroIngredientInput): boolean {
  return Boolean(
    ing.catalogItemId && ing.amountGrams != null && ing.amountGrams > 0 && !hasNonMacroUnit(ing.unit),
  );
}

export function isUnlinkedMacroIngredient(ing: MacroIngredientInput): boolean {
  if (!ing.name?.trim()) return false;
  if (hasNonMacroUnit(ing.unit)) return false;
  return Boolean(ing.amountGrams != null && ing.amountGrams > 0 && !ing.catalogItemId);
}

export function countUnlinkedMacroIngredients(ingredients: MacroIngredientInput[]): number {
  return ingredients.filter(isUnlinkedMacroIngredient).length;
}

export function estimateMacrosFromCatalog(
  ingredients: MacroIngredientInput[],
  catalogItems: Pick<
    IngredientNutritionItem,
    "id" | "caloriesPer100G" | "proteinGPer100G" | "fatGPer100G" | "carbsGPer100G"
  >[],
): MacroTotals | null {
  let calories = 0;
  let protein = 0;
  let fat = 0;
  let carbs = 0;
  let hasAny = false;

  for (const ing of ingredients) {
    if (!shouldIncludeIngredientInMacroSum(ing)) continue;
    const cat = catalogItems.find((c) => c.id === ing.catalogItemId);
    if (!cat) continue;
    const scale = Number(ing.amountGrams) / 100;
    calories += Math.round(cat.caloriesPer100G * scale);
    protein += cat.proteinGPer100G * scale;
    fat += cat.fatGPer100G * scale;
    carbs += cat.carbsGPer100G * scale;
    hasAny = true;
  }

  return hasAny ? { calories, protein, fat, carbs } : null;
}
