import {
  INGREDIENT_CATEGORIES,
  type IngredientCategory,
  type ShoppingListItemView,
} from "@batch-cooking/shared";

/** One aisle's worth of shopping list lines — see {@link groupShoppingListItems}. */
export interface ShoppingListGroup {
  category: IngredientCategory;
  items: ShoppingListItemView[];
}

/**
 * Groups `items` by their ingredient's supermarket-aisle category (the same
 * `IngredientCategory` the recipe form's `IngredientPicker` already browses
 * by, see `ingredient-icons.tsx`'s `CategoryIcon`), in the app's canonical
 * `INGREDIENT_CATEGORIES` order — a shopping list read aisle-by-aisle is far
 * more useful in-store than one flat list. Within a group, lines are sorted
 * by `ingredientLabel` — the caller's *already-translated* display name for
 * that line, not the untranslated English `key` — so alphabetical order
 * reads correctly in French; kept as a parameter (rather than calling
 * `useTranslation` in here) so this stays a pure function the component can
 * unit test without mounting i18next, same "logic extracted from the .tsx"
 * split as every other feature in this codebase.
 */
export function groupShoppingListItems(
  items: ShoppingListItemView[],
  ingredientLabel: (item: ShoppingListItemView) => string,
): ShoppingListGroup[] {
  const byCategory = new Map<IngredientCategory, ShoppingListItemView[]>();
  for (const item of items) {
    const category = item.ingredient.category;
    const group = byCategory.get(category);
    if (group) {
      group.push(item);
    } else {
      byCategory.set(category, [item]);
    }
  }

  const groups: ShoppingListGroup[] = [];
  for (const category of INGREDIENT_CATEGORIES) {
    const groupItems = byCategory.get(category);
    if (!groupItems) continue;
    groups.push({
      category,
      items: [...groupItems].sort((a, b) =>
        ingredientLabel(a).localeCompare(ingredientLabel(b), "fr"),
      ),
    });
  }
  return groups;
}

/**
 * Formats an aggregated quantity for display — French grouping/decimal
 * conventions, at most 2 decimals (e.g. `"1,5"`, `"250"`) so summing several
 * recipes' quantities (`shopping-list.service.ts`'s `aggregateShoppingList`,
 * floating-point addition) never surfaces a long trailing-digit artifact
 * like `"149.99999999999997"`.
 */
export function formatShoppingListQuantity(quantity: number): string {
  return quantity.toLocaleString("fr-FR", { maximumFractionDigits: 2 });
}
