import { useMemo, useState } from "react";
import { Clock } from "lucide-react";
import { useTranslation } from "react-i18next";
import { CategoryBadge } from "@/components/ui/CategoryBadge";
import type { RecipeDetail as RecipeDetailModel } from "@/types/recipe.types";
import { nextSort, sortBy, sortIndicator, type SortDirection } from "@/utils/sort.util";

type IngredientSortColumn = "name" | "amount";

interface MacroProps {
  label: string;
  value: number | null;
  suffix: string;
  accent: string;
}

function Macro({ label, value, suffix, accent }: MacroProps) {
  return (
    <div className="rounded-2xl border border-slate-200 bg-white px-4 py-3 text-center dark:border-slate-800 dark:bg-slate-900">
      <p className={`text-2xl font-extrabold ${accent}`}>
        {value != null ? value : "—"}
        {value != null && <span className="text-sm font-semibold"> {suffix}</span>}
      </p>
      <p className="mt-0.5 text-xs font-medium uppercase tracking-wide text-slate-500 dark:text-slate-400">
        {label}
      </p>
    </div>
  );
}

function formatAmount(amount: number | null, unit: string | null): string {
  if (amount == null && !unit) return "";
  if (amount == null) return unit ?? "";
  const display = Number.isInteger(amount) ? amount.toString() : amount.toString();
  return unit ? `${display} ${unit}` : `${display} g`;
}

interface RecipeDetailProps {
  recipe: RecipeDetailModel;
}

export function RecipeDetail({ recipe }: RecipeDetailProps) {
  const { t } = useTranslation();
  const [ingredientSort, setIngredientSort] = useState<{
    column: IngredientSortColumn;
    direction: SortDirection;
  }>({ column: "name", direction: "asc" });

  const sortedIngredients = useMemo(
    () =>
      sortBy(recipe.ingredients, ingredientSort.direction, (ing) =>
        ingredientSort.column === "name" ? ing.name : ing.amountGrams,
      ),
    [recipe.ingredients, ingredientSort],
  );

  const toggleIngredientSort = (column: IngredientSortColumn) => {
    setIngredientSort((current) => nextSort(current, column));
  };

  return (
    <article className="space-y-8">
      <header className="space-y-3">
        <CategoryBadge category={recipe.mealCategory} />
        <h1 className="text-3xl font-extrabold tracking-tight">{recipe.name}</h1>
        {recipe.prepTimeMinutes != null && (
          <p className="inline-flex items-center gap-1.5 text-sm text-slate-500 dark:text-slate-400">
            <Clock className="h-4 w-4" />
            {t("recipes.prepTime", { count: recipe.prepTimeMinutes })}
          </p>
        )}
      </header>

      <section className="grid grid-cols-2 gap-3 sm:grid-cols-4">
        <Macro label={t("recipes.calories")} value={recipe.calories} suffix="kcal" accent="text-orange-500" />
        <Macro label={t("recipes.protein")} value={recipe.protein} suffix="g" accent="text-brand-600" />
        <Macro label={t("recipes.fat")} value={recipe.fat} suffix="g" accent="text-amber-500" />
        <Macro label={t("recipes.carbs")} value={recipe.carbs} suffix="g" accent="text-sky-500" />
      </section>

      <div className="grid gap-8 lg:grid-cols-[1fr_1.4fr]">
        <section>
          <h2 className="text-lg font-bold">{t("recipes.ingredients")}</h2>
          {recipe.ingredients.length === 0 ? (
            <p className="mt-3 text-sm text-slate-500">{t("recipes.noIngredients")}</p>
          ) : (
            <div className="mt-4 overflow-hidden rounded-2xl border border-slate-200 dark:border-slate-800">
              <div className="grid grid-cols-[1fr_auto] border-b border-slate-200 bg-slate-50 px-4 py-2 text-xs font-semibold uppercase tracking-wide text-slate-500 dark:border-slate-800 dark:bg-slate-800/50">
                <button
                  type="button"
                  className="text-left hover:text-slate-700 dark:hover:text-slate-200"
                  onClick={() => toggleIngredientSort("name")}
                >
                  {t("ingredientCatalog.columns.name")}
                  {sortIndicator(ingredientSort, "name")}
                </button>
                <button
                  type="button"
                  className="text-right hover:text-slate-700 dark:hover:text-slate-200"
                  onClick={() => toggleIngredientSort("amount")}
                >
                  {t("diet.grams")}
                  {sortIndicator(ingredientSort, "amount")}
                </button>
              </div>
              <ul className="divide-y divide-slate-200 dark:divide-slate-800">
                {sortedIngredients.map((ing) => (
                  <li key={ing.id} className="grid grid-cols-[1fr_auto] items-center px-4 py-3 text-sm">
                    <span>{ing.name}</span>
                    <span className="font-medium text-slate-500 dark:text-slate-400">
                      {formatAmount(ing.amountGrams, ing.unit)}
                    </span>
                  </li>
                ))}
              </ul>
            </div>
          )}
        </section>

        <section>
          <h2 className="text-lg font-bold">{t("recipes.preparation")}</h2>
          {recipe.steps.length === 0 ? (
            <p className="mt-3 text-sm text-slate-500">{t("recipes.noSteps")}</p>
          ) : (
            <ol className="mt-4 space-y-4">
              {recipe.steps.map((step) => (
                <li key={step.id} className="flex gap-4">
                  <span className="grid h-8 w-8 shrink-0 place-items-center rounded-full bg-brand-600 text-sm font-bold text-white">
                    {step.stepNumber}
                  </span>
                  <p className="pt-1 text-sm leading-relaxed text-slate-700 dark:text-slate-300">
                    {step.description}
                  </p>
                </li>
              ))}
            </ol>
          )}
        </section>
      </div>
    </article>
  );
}
