import type { IngredientView, UnitView } from "@batch-cooking/shared";
import { useTranslation } from "react-i18next";
import { AllergenBadges } from "../badges/AllergenBadges";
import { DietBadges } from "../badges/DietBadges";
import { ReproducibleBadge } from "../badges/ReproducibleBadge";
import { IngredientTypeIcon } from "./ingredient-icons";
import { ingredientLabel } from "./ingredient-label";
import "../recipes.scss";

/** One selected ingredient line in the recipe form — the ingredient itself (picked via `IngredientPicker`) plus its quantity/unit for this recipe. Quantity is kept as a raw string while editing (not parsed to a number until submit) so an in-progress/invalid value doesn't fight the input; `unit` picks from `unitsCatalog` (a closed reference list, see `Unit` in schema.prisma) rather than free text. */
export function IngredientRow({
  ingredient,
  quantity,
  unitId,
  unitsCatalog,
  duplicate = false,
  onQuantityChange,
  onUnitChange,
  onRemove,
}: {
  ingredient: IngredientView;
  quantity: string;
  unitId: number | null;
  unitsCatalog: UnitView[];
  /** This ingredient is also picked by another line in the same form — `RecipeIngredient`'s primary key is `(recipeId, ingredientId)`, one row per ingredient (schema.prisma), so submitting two lines for it would fail. Never true for a manually-added line (`IngredientPicker`'s `excludeIds` already prevents picking the same ingredient twice) — only reachable via a source import, whose raw lines aren't deduplicated (e.g. "Egg Yolks" and "Eggs" both resolving to "Egg" — see issue #53's `RecipeImportForm`). */
  duplicate?: boolean;
  onQuantityChange: (quantity: string) => void;
  onUnitChange: (unitId: number) => void;
  onRemove: () => void;
}) {
  const { t } = useTranslation();
  // No unit picked yet — surfaced with a highlighted `<select>` + inline
  // hint rather than silently keeping the form's submit button disabled
  // (see issue #53: an import pre-filled from a source can land here with
  // an ingredient resolved but no unit — e.g. a bare count like "4 Egg
  // Yolks" — and nothing used to tell the user which line was blocking
  // them, or why).
  const unitMissing = unitId === null;
  const needsAttention = unitMissing || duplicate;
  // A free-text placeholder line (the catalog had nothing matching) — shown
  // with an "à compléter" badge and none of the allergen/diet/reproducible
  // badges, which carry no meaning until a maintainer promotes it to a real
  // catalog entry. Its quantity/unit still work exactly like any other line.
  const isPlaceholder = ingredient.isPlaceholder;

  return (
    <li className={needsAttention ? "ingredient-row ingredient-row--incomplete" : "ingredient-row"}>
      <span className="ingredient-row__icon" aria-hidden="true">
        <IngredientTypeIcon icon={ingredient.icon} />
      </span>
      <span className="ingredient-row__name">
        {ingredientLabel(ingredient, t)}
        {isPlaceholder && (
          <span className="ingredient-row__placeholder-badge">
            {t("recipes.form.placeholderBadge")}
          </span>
        )}
      </span>
      <input
        type="number"
        min="0"
        step="any"
        className="ingredient-row__quantity"
        value={quantity}
        onChange={(e) => onQuantityChange(e.target.value)}
        aria-label={t("recipes.form.quantityLabel")}
      />
      <select
        className="ingredient-row__unit"
        value={unitId ?? ""}
        onChange={(e) => onUnitChange(Number(e.target.value))}
        aria-label={t("recipes.form.unitLabel")}
        aria-invalid={unitMissing}
      >
        <option value="" disabled>
          {t("recipes.form.unitPlaceholder")}
        </option>
        {unitsCatalog.map((unit) => (
          <option key={unit.id} value={unit.id}>
            {t(`catalog.units.${unit.key}`)}
          </option>
        ))}
      </select>
      {!isPlaceholder && (
        <>
          <AllergenBadges allergens={ingredient.allergens} />
          <DietBadges diets={ingredient.diets} />
          <ReproducibleBadge
            reproducible={ingredient.reproducible}
            searchLabel={ingredientLabel(ingredient, t)}
          />
        </>
      )}
      <button
        type="button"
        className="ingredient-row__remove"
        onClick={onRemove}
        title={t("recipes.form.removeIngredient")}
      >
        ✕
      </button>
      {unitMissing && (
        <p className="field-error ingredient-row__error">{t("recipes.form.unitMissingHint")}</p>
      )}
      {duplicate && (
        <p className="field-error ingredient-row__error">
          {t("recipes.form.duplicateIngredientHint")}
        </p>
      )}
    </li>
  );
}
