import type { Meal, RecipeImportDraftView, WeekDay } from "@batch-cooking/shared";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
import { StepDescription } from "./StepDescription";
import "./recipes.scss";

/** State {@link SourceItemPreviewPanel} renders — mirrors `RecipeDetailState`'s shape (`RecipeDetailPanel`), one status short (no "not-found": an invalid `externalId` surfaces as `"error"`, there's no separate "id was well-formed but nothing matched it" case here). */
export type SourceItemPreviewState =
  | { status: "empty" }
  | { status: "loading" }
  | { status: "loaded"; draft: RecipeImportDraftView }
  | { status: "error" };

/**
 * Right-hand panel of the catalog's "Sources" tab (`RecipeSourcesPanel`) —
 * a read-only preview of a not-yet-imported item: nothing here can be
 * edited or saved yet (no favorite/edit/delete actions, unlike
 * `RecipeDetailPanel`) — turning this into an actual import with a review
 * step for unresolved ingredients is a later stage of the same plan.
 * Reuses `StepDescription` so a step's detected techniques are already
 * highlighted here too, exactly like a saved recipe's detail.
 */
export function SourceItemPreviewPanel({
  state,
  planningSlot,
}: {
  state: SourceItemPreviewState;
  /**
   * Set only when this panel is rendered from `RecipePickerDialog` (adding a
   * recipe to one planning slot) rather than the standalone `/recettes`
   * catalog — carried along on the "Importer cette recette" link as query
   * params so `ImportRecipePage` knows to add the freshly-created recipe to
   * this exact slot once the import succeeds, instead of landing on the
   * recipe's own detail page. See `ImportRecipePage`'s `planningSlot`.
   */
  planningSlot?: { date: string; weekDay: WeekDay; meal: Meal };
}) {
  const { t } = useTranslation();

  if (state.status === "empty") {
    return (
      <aside className="recipe-detail-panel">
        <p className="recipe-detail-panel__status">{t("recipes.sources.detail.empty")}</p>
      </aside>
    );
  }
  if (state.status === "loading") {
    return (
      <aside className="recipe-detail-panel">
        <p className="recipe-detail-panel__status">{t("recipes.sources.detail.loading")}</p>
      </aside>
    );
  }
  if (state.status === "error") {
    return (
      <aside className="recipe-detail-panel">
        <p className="recipe-detail-panel__status recipe-detail-panel__status--error">
          {t("recipes.sources.detail.loadError")}
        </p>
      </aside>
    );
  }

  const { draft } = state;
  const hasUnresolvedIngredient = draft.ingredients.some(
    (ingredient) => ingredient.ingredient === null,
  );

  return (
    <aside className="recipe-detail-panel">
      <div className="recipe-detail-panel__header">
        <div className="recipe-detail-panel__photo" aria-hidden="true">
          {draft.picture ? <img src={draft.picture} alt="" /> : "🍽️"}
        </div>
      </div>

      <div className="recipe-detail-panel__title-row">
        <div className="recipe-detail-panel__title-main">
          <h2>{draft.name}</h2>
          {draft.portions !== null && (
            <p className="recipe-detail-panel__portions">
              {t("recipes.detail.portions", { count: draft.portions })}
            </p>
          )}
        </div>
      </div>

      <div className="recipe-detail-panel__actions">
        <Link
          to={{
            pathname: `/recettes/importer/${draft.sourceKey}/${encodeURIComponent(draft.externalId)}`,
            search: planningSlot
              ? `?planningDate=${planningSlot.date}&planningWeekDay=${planningSlot.weekDay}&planningMeal=${planningSlot.meal}`
              : undefined,
          }}
          className="recipes-page__new-button"
        >
          {t("recipes.sources.detail.importButton")}
        </Link>
        <a
          href={draft.sourceUrl}
          target="_blank"
          rel="noreferrer"
          className="recipes-page__new-button"
        >
          {t("recipes.sources.detail.viewSource")}
        </a>
      </div>

      {draft.description && (
        <section className="recipe-detail-panel__section recipe-detail-panel__section--description">
          <p className="recipe-detail-panel__description">{draft.description}</p>
        </section>
      )}

      <section className="recipe-detail-panel__section">
        <h3>{t("recipes.sources.detail.ingredientsCount", { count: draft.ingredients.length })}</h3>
        {hasUnresolvedIngredient && (
          <p className="source-item-preview__hint">
            {t("recipes.sources.detail.unresolvedIngredientsHint")}
          </p>
        )}
        <ul className="source-item-preview__ingredients">
          {draft.ingredients.map((ingredient, index) => (
            // Draft lines have no id of their own (nothing is saved yet) —
            // `rawText` alone could collide (a source repeating the same
            // line), so it's paired with its position; this list is fully
            // regenerated from `draft` on every render, never reordered in
            // place, so that's safe here (same reasoning as
            // StepDescription.tsx's segment keys).
            <li
              key={`${index}-${ingredient.rawText}`}
              className={ingredient.ingredient === null ? "is-unresolved" : undefined}
            >
              {ingredient.rawText}
            </li>
          ))}
        </ul>
      </section>

      <section className="recipe-detail-panel__section">
        <h3>{t("recipes.sources.detail.stepsCount", { count: draft.steps.length })}</h3>
        <ol className="recipe-detail-panel__steps">
          {draft.steps.map((step, index) => (
            <li key={`${index}-${step.description}`}>
              {step.picture && <img src={step.picture} alt="" />}
              <StepDescription description={step.description} techSteps={step.techSteps} />
            </li>
          ))}
        </ol>
      </section>
    </aside>
  );
}
