import type { IngredientView, TechStepView, UnitView, UtensilView } from "./reference.js";

/**
 * A recipe that contributes to an optimized cooking plan, resolved to just
 * enough for a display legend / provenance badge — same "resolve to
 * `{id, name}` and nothing more" treatment as `PlanningItemView.recipe`.
 * `portions` is this contribution's own portion count (the `PlanningItem`'s,
 * not `Recipe.portions`), since the plan scales quantities to it.
 */
export interface CookingSessionRecipeRef {
  recipeId: number;
  name: string;
  portions: number;
}

/**
 * Which stage of the session a {@link CookingPhaseView} belongs to. Not a
 * free-form title — the label is resolved client-side via
 * `t(\`cookingSession.phase.${kind}\`)`, same "API sends a key, web owns the
 * wording" split as every reference catalog:
 *
 * - `"mise-en-place"` — the first phase: all shared prep pooled together
 *   (`chop`/`peel`/… the same ingredient across recipes = one task) plus
 *   `SETUP` tasks (preheat the oven, bring water to a boil).
 * - `"cooking"` — the interleaved middle phases, one "next ready step of
 *   each recipe" per phase, with passive cooks floated into `background`.
 * - `"finishing"` — the last phase when it only holds plating/`plate` work.
 */
export type CookingPhaseKind = "mise-en-place" | "cooking" | "finishing";

/**
 * One ingredient line attached to a {@link CookingTaskView} — the same
 * `(ingredient, quantity, unit)` shape as `StepTechStepIngredientView`,
 * carried through so the cook sees "3 oignons" next to "Émincer". Both
 * `quantity` and `unit` are `null` when the source clause named the
 * ingredient with no measurable amount ("ajouter le sel"), or when a
 * merge pooled two incompatible units and no single total could be given
 * (see {@link CookingTaskView.kind}).
 */
export interface CookingTaskIngredientView {
  ingredient: IngredientView;
  quantity: number | null;
  unit: UnitView | null;
}

/**
 * One actionable unit of work in a phase's `tasks` list.
 *
 * - `kind: "step"` — a single recipe step, run as written. `technique` is
 *   its dominant detected technique (or `null` if it mentions none),
 *   `description` is the original step text, `sourceRecipes` has exactly one
 *   entry.
 * - `kind: "merged-prep"` — shared preparation pooled across recipes: the
 *   same prep technique applied to the same ingredient by two or more
 *   recipes, collapsed into one task (the "mutualise the onions" case).
 *   `description` is `null` (the web layer composes a label from
 *   `technique` + `ingredients`), `sourceRecipes` lists every recipe it
 *   covers, and `ingredients` holds the pooled quantity.
 *
 * `id` is stable within a single response (`"prep:<techniqueKey>:<ingredientKey>"`
 * or `"step:<stepId>"`) so the frontend can key a checklist off it.
 * `originalSteps` is the provenance trail — the exact step text(s) this
 * task stands in for, so the UI can link back to "voir la recette".
 */
export interface CookingTaskView {
  id: string;
  kind: "merged-prep" | "step";
  technique: TechStepView | null;
  description: string | null;
  ingredients: CookingTaskIngredientView[];
  utensils: UtensilView[];
  sourceRecipes: CookingSessionRecipeRef[];
  originalSteps: { recipeId: number; recipeName: string; description: string }[];
}

/**
 * A passive cook (simmer, braise, bake, marinate…) started in an earlier
 * phase and still running — surfaced in every later phase's `background`
 * until the step that consumes it comes up, so the cook is reminded "the
 * beef is still braising" while doing active work from another recipe. Not
 * something to act on now, just a status line, hence a thinner shape than
 * {@link CookingTaskView}.
 */
export interface CookingBackgroundTaskView {
  id: string;
  technique: TechStepView | null;
  description: string;
  recipeId: number;
  recipeName: string;
}

/**
 * One phase of the optimized plan: a batch of work the cook does now
 * (`tasks`), plus any passive cooks carried over from before (`background`).
 * `index` is 0-based and matches the array position — carried explicitly so
 * a caller rendering a single phase still knows where it sits.
 */
export interface CookingPhaseView {
  index: number;
  kind: CookingPhaseKind;
  tasks: CookingTaskView[];
  background: CookingBackgroundTaskView[];
}

/**
 * A household's week of planned recipes, reorganized into an ordered
 * sequence of cooking phases (see `apps/api`'s `cooking-optimizer.ts`).
 *
 * Like `ShoppingListView` and unlike `PlanningView`, this is **never**
 * `null` — no household, or a household with nothing planned that week,
 * both degrade to an empty `phases` array on an otherwise normal object
 * (the week's date range is always computable), not a separate "nothing to
 * show" state the frontend has to branch on.
 */
export interface OptimizedCookingPlanView {
  startDate: string;
  finishDate: string;
  recipes: CookingSessionRecipeRef[];
  phases: CookingPhaseView[];
}
