"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import Link from "next/link";
import { useAdmin } from "@/context/AdminContext";
import { StatusPill } from "@/components/admin/NegocioShell";
import {
  CATEGORY_OPTIONS,
  DEFAULT_SPECS,
  formatCopAdmin,
  formatCopInput,
  parseCopInput,
  parseSizesInput,
  resolveCategoryMeta,
  slugifyCategory,
  OT_COLOR_PRESETS,
  OT_SWATCH_PALETTE,
  type AdminCategory,
  type AdminColorWay,
  type AdminProduct,
  type AdminSpec,
} from "@/lib/product-admin";

type Mode = "list" | "create" | "edit";

const STEP_LABELS = ["Categoría", "Datos", "Colores", "Ficha"] as const;

function slugify(input: string) {
  return input
    .toLowerCase()
    .normalize("NFD")
    .replace(/\p{Diacritic}/gu, "")
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/^-|-$/g, "")
    .slice(0, 64);
}

const emptyColor = (): AdminColorWay => ({
  name: "",
  swatches: ["#1B3A2F", "#F3EFE5"],
  images: [],
});

export function ProductAdminPanel() {
  const { authenticated, loading: authLoading } = useAdmin();
  const [products, setProducts] = useState<AdminProduct[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [query, setQuery] = useState("");
  const [mode, setMode] = useState<Mode>("list");
  const [step, setStep] = useState(1);
  const [busy, setBusy] = useState(false);
  const [editingId, setEditingId] = useState<string | null>(null);

  // wizard state
  const [category, setCategory] = useState<AdminCategory>("mujer");
  const [customCategoryName, setCustomCategoryName] = useState("");
  const [customSizesText, setCustomSizesText] = useState("S, M, L, XL");
  const [usingCustomCategory, setUsingCustomCategory] = useState(false);
  const [title, setTitle] = useState("");
  const [handle, setHandle] = useState("");
  const [description, setDescription] = useState("");
  const [collection, setCollection] = useState("Sporty Elegance");
  const [tagline, setTagline] = useState("Clásico. Elegancia con carácter.");
  const [price, setPrice] = useState(199900);
  const [stockQty, setStockQty] = useState(10);
  const [colorWays, setColorWays] = useState<AdminColorWay[]>([emptyColor()]);
  const [specs, setSpecs] = useState<AdminSpec[]>(DEFAULT_SPECS);
  const [success, setSuccess] = useState<string | null>(null);
  const [handleTouched, setHandleTouched] = useState(false);

  const customSizes = useMemo(
    () => parseSizesInput(customSizesText),
    [customSizesText]
  );

  const catMeta = useMemo(
    () =>
      resolveCategoryMeta(category, {
        label: customCategoryName || category,
        sizes: usingCustomCategory ? customSizes : undefined,
        collection,
      }),
    [category, customCategoryName, usingCustomCategory, customSizes, collection]
  );

  const validColors = colorWays.filter(
    (c) => c.name.trim() && c.images.length
  ).length;

  const canGoTo = (n: number) => {
    if (n <= 1) return true;
    if (n === 2) {
      if (usingCustomCategory) {
        return (
          Boolean(slugifyCategory(customCategoryName)) && customSizes.length > 0
        );
      }
      return Boolean(category);
    }
    if (n === 3) return Boolean(title.trim()) && price > 0;
    if (n === 4) return validColors > 0;
    return false;
  };

  const load = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const res = await fetch("/api/ops/products", { cache: "no-store" });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) throw new Error(data.message || "Error al listar");
      setProducts(data.products || []);
    } catch (e) {
      setError(e instanceof Error ? e.message : "Error al listar");
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    if (authenticated) void load();
  }, [authenticated, load]);

  const filtered = useMemo(() => {
    const q = query.trim().toLowerCase();
    if (!q) return products;
    return products.filter(
      (p) =>
        p.title.toLowerCase().includes(q) ||
        p.handle.toLowerCase().includes(q) ||
        p.category.toLowerCase().includes(q)
    );
  }, [products, query]);

  const resetWizard = (cat: AdminCategory = "mujer") => {
    const meta = resolveCategoryMeta(cat);
    setCategory(cat);
    setUsingCustomCategory(false);
    setCustomCategoryName("");
    setCustomSizesText("S, M, L, XL");
    setTitle("");
    setHandle("");
    setDescription("");
    setCollection(meta.collection);
    setTagline("Clásico. Elegancia con carácter.");
    setPrice(199900);
    setStockQty(10);
    setColorWays([emptyColor()]);
    setSpecs([...DEFAULT_SPECS]);
    setStep(1);
    setEditingId(null);
    setError(null);
    setSuccess(null);
    setHandleTouched(false);
  };

  const startCreate = () => {
    resetWizard("mujer");
    setMode("create");
  };

  const startEdit = (p: AdminProduct) => {
    setMode("edit");
    setEditingId(p.id);
    const cat = p.category || "mujer";
    const isPreset = CATEGORY_OPTIONS.some((c) => c.id === cat);
    setCategory(cat);
    setUsingCustomCategory(!isPreset);
    setCustomCategoryName(isPreset ? "" : cat.replace(/-/g, " "));
    setCustomSizesText(
      p.sizes?.length ? p.sizes.join(", ") : "S, M, L, XL"
    );
    setTitle(p.title);
    setHandle(p.handle);
    setDescription(p.description);
    setCollection(p.collection || "Club 1976");
    setTagline(p.tagline || "");
    setPrice(p.price || 0);
    setColorWays(
      p.color_ways?.length
        ? p.color_ways.map((c) => ({
            name: c.name,
            swatches: [
              c.swatches?.[0] || "#1B3A2F",
              c.swatches?.[1] || "#F3EFE5",
            ],
            images: c.images || [],
          }))
        : [emptyColor()]
    );
    setSpecs(p.specs?.length ? p.specs : [...DEFAULT_SPECS]);
    setStep(1);
    setError(null);
    setSuccess(null);
    setHandleTouched(true);
  };

  const uploadFile = async (file: File, colorName: string) => {
    const fd = new FormData();
    fd.append("file", file);
    fd.append("folder", handle || title || "nuevo");
    fd.append("color", colorName || "color");
    const res = await fetch("/api/ops/products/upload", {
      method: "POST",
      body: fd,
    });
    const data = await res.json().catch(() => ({}));
    if (!res.ok) throw new Error(data.message || "Error al subir");
    return String(data.absolute || data.url);
  };

  const publish = async () => {
    setBusy(true);
    setError(null);
    try {
      const cleanedWays = colorWays
        .map((c) => ({
          name: c.name.trim(),
          swatches: c.swatches,
          images: c.images.filter(Boolean),
        }))
        .filter((c) => c.name && c.images.length);

      if (!title.trim()) throw new Error("El nombre es obligatorio.");
      if (!cleanedWays.length) {
        throw new Error("Agrega al menos un color con nombre y fotos.");
      }
      if (!price || price <= 0) throw new Error("Precio inválido.");

      if (mode === "create") {
        const res = await fetch("/api/ops/products", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            title: title.trim(),
            handle: handle.trim() || undefined,
            description: description.trim(),
            category,
            collection,
            tagline,
            price,
            sizes: catMeta.sizes,
            color_ways: cleanedWays,
            specs: specs.filter((s) => s.label.trim() && s.value.trim()),
            stock_qty: stockQty,
          }),
        });
        const data = await res.json().catch(() => ({}));
        if (!res.ok) throw new Error(data.message || "No se pudo crear");
      } else if (editingId) {
        const res = await fetch(`/api/ops/products/${editingId}`, {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            title: title.trim(),
            description: description.trim(),
            category,
            collection,
            tagline,
            price,
            color_ways: cleanedWays,
            specs: specs.filter((s) => s.label.trim() && s.value.trim()),
          }),
        });
        const data = await res.json().catch(() => ({}));
        if (!res.ok) throw new Error(data.message || "No se pudo guardar");
      }

      setMode("list");
      setSuccess(
        mode === "create"
          ? "Producto publicado en la tienda."
          : "Cambios guardados."
      );
      await load();
    } catch (e) {
      setError(e instanceof Error ? e.message : "Error al guardar");
    } finally {
      setBusy(false);
    }
  };

  const toggleStatus = async (p: AdminProduct) => {
    const next = p.status === "published" ? "draft" : "published";
    const res = await fetch(`/api/ops/products/${p.id}/status`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ status: next }),
    });
    const data = await res.json().catch(() => ({}));
    if (!res.ok) {
      setError(data.message || "No se pudo cambiar estado");
      return;
    }
    await load();
  };

  const remove = async (p: AdminProduct) => {
    if (
      !confirm(
        `¿Eliminar "${p.title}"? Dejará de verse en la tienda (se puede recuperar desde Medusa si hace falta).`
      )
    ) {
      return;
    }
    const res = await fetch(`/api/ops/products/${p.id}`, { method: "DELETE" });
    const data = await res.json().catch(() => ({}));
    if (!res.ok) {
      setError(data.message || "No se pudo eliminar");
      return;
    }
    await load();
  };

  if (authLoading || !authenticated) return null;

  if (mode !== "list") {
    return (
      <div className="space-y-6 max-w-3xl">
        <div className="flex flex-wrap items-center gap-3">
          <p className="ot-eyebrow">Fase E</p>
          <StatusPill status="activo" />
        </div>
        <div className="flex flex-wrap items-end justify-between gap-3">
          <div>
            <h1 className="font-serif text-4xl">
              {mode === "create" ? "Nuevo producto" : "Editar producto"}
            </h1>
            <p className="text-ot-muted mt-1 text-sm">
              {STEP_LABELS[step - 1]} · el layout OT se arma solo
            </p>
          </div>
          <button
            type="button"
            className="ot-btn ot-btn-ghost"
            onClick={() => setMode("list")}
          >
            Volver al listado
          </button>
        </div>

        <div className="flex gap-1.5">
          {STEP_LABELS.map((label, i) => {
            const n = i + 1;
            const active = step === n;
            const done = step > n;
            return (
              <button
                key={label}
                type="button"
                disabled={!canGoTo(n) && n > step}
                onClick={() => {
                  if (n < step || canGoTo(n)) setStep(n);
                }}
                className={`flex-1 min-w-0 px-2 py-2 text-[10px] sm:text-[11px] tracking-[0.12em] uppercase border transition ${
                  active
                    ? "border-ot-green bg-ot-green text-ot-cream"
                    : done
                      ? "border-ot-green/40 bg-white text-ot-green"
                      : "border-black/10 text-ot-muted"
                }`}
              >
                <span className="hidden sm:inline">{n}. </span>
                {label}
              </button>
            );
          })}
        </div>

        {error && (
          <p className="text-sm text-red-700 border border-red-700/20 bg-red-700/[0.04] px-3 py-2">
            {error}
          </p>
        )}

        {step === 1 && (
          <div className="space-y-4">
            <div className="grid sm:grid-cols-2 gap-3">
              {CATEGORY_OPTIONS.map((c) => (
                <button
                  key={c.id}
                  type="button"
                  onClick={() => {
                    setUsingCustomCategory(false);
                    setCustomCategoryName("");
                    setCategory(c.id);
                    setCollection(c.collection);
                  }}
                  className={`text-left border p-4 transition ${
                    !usingCustomCategory && category === c.id
                      ? "border-ot-green bg-white"
                      : "border-black/10 bg-white/60 hover:border-ot-green/40"
                  }`}
                >
                  <p className="font-serif text-xl">{c.label}</p>
                  <p className="text-sm text-ot-muted mt-1">{c.hint}</p>
                  <p className="text-[11px] tracking-[0.12em] uppercase text-ot-gold mt-3">
                    Tallas: {c.sizes.join(" · ")}
                  </p>
                </button>
              ))}
            </div>

            <div
              className={`border p-4 space-y-3 transition ${
                usingCustomCategory
                  ? "border-ot-green bg-white"
                  : "border-dashed border-black/20 bg-ot-cream-dark/30"
              }`}
            >
              <button
                type="button"
                className="w-full text-left"
                onClick={() => {
                  setUsingCustomCategory(true);
                  const id = slugifyCategory(customCategoryName) || "nueva";
                  setCategory(id);
                  setCollection("Club 1976");
                }}
              >
                <p className="font-serif text-xl">Otra categoría</p>
                <p className="text-sm text-ot-muted mt-1">
                  Ej. Zapatos, Gorras premium, Kids… Tú defines el nombre y las
                  tallas.
                </p>
              </button>

              {usingCustomCategory ? (
                <div className="grid sm:grid-cols-2 gap-3 pt-1">
                  <div>
                    <label className="ot-label-condensed text-[11px] text-ot-muted">
                      Nombre de la categoría
                    </label>
                    <input
                      className="mt-2 w-full border border-black/15 px-3 py-2.5 text-sm"
                      placeholder="Ej. Zapatos"
                      value={customCategoryName}
                      onChange={(e) => {
                        const v = e.target.value;
                        setCustomCategoryName(v);
                        setCategory(slugifyCategory(v) || "nueva");
                      }}
                      autoFocus
                    />
                    {customCategoryName.trim() ? (
                      <p className="mt-1 text-[11px] text-ot-muted">
                        ID: {slugifyCategory(customCategoryName) || "—"}
                      </p>
                    ) : null}
                  </div>
                  <div>
                    <label className="ot-label-condensed text-[11px] text-ot-muted">
                      Tallas (separadas por coma)
                    </label>
                    <input
                      className="mt-2 w-full border border-black/15 px-3 py-2.5 text-sm"
                      placeholder="35, 36, 37, 38, 39, 40"
                      value={customSizesText}
                      onChange={(e) => setCustomSizesText(e.target.value)}
                    />
                    <p className="mt-1 text-[11px] text-ot-muted">
                      {customSizes.length
                        ? customSizes.join(" · ")
                        : "Indica al menos una talla"}
                    </p>
                  </div>
                </div>
              ) : null}
            </div>
          </div>
        )}

        {step === 2 && (
          <div className="bg-white border border-black/10 p-5 space-y-4">
            <div>
              <label className="ot-label-condensed text-[11px]">Nombre</label>
              <input
                className="mt-2 w-full border border-black/15 px-3 py-2.5 text-sm"
                value={title}
                onChange={(e) => {
                  const v = e.target.value;
                  setTitle(v);
                  if (mode === "create" && !handleTouched) {
                    setHandle(slugify(v));
                  }
                }}
                placeholder="Ej. Polo Club 1976"
              />
            </div>
            {mode === "create" && (
              <div>
                <label className="ot-label-condensed text-[11px]">
                  URL en la tienda
                </label>
                <div className="mt-2 flex items-center gap-0 border border-black/15 bg-ot-cream/40">
                  <span className="px-3 text-xs text-ot-muted shrink-0">
                    /product/
                  </span>
                  <input
                    className="w-full bg-white px-3 py-2.5 text-sm outline-none"
                    value={handle}
                    onChange={(e) => {
                      setHandleTouched(true);
                      setHandle(slugify(e.target.value) || e.target.value);
                    }}
                    placeholder="se genera del nombre"
                  />
                </div>
              </div>
            )}
            <div>
              <label className="ot-label-condensed text-[11px]">
                Colección
              </label>
              <input
                className="mt-2 w-full border border-black/15 px-3 py-2.5 text-sm"
                value={collection}
                onChange={(e) => setCollection(e.target.value)}
              />
            </div>
            <div>
              <label className="ot-label-condensed text-[11px]">
                Enunciado / tagline
              </label>
              <input
                className="mt-2 w-full border border-black/15 px-3 py-2.5 text-sm"
                value={tagline}
                onChange={(e) => setTagline(e.target.value)}
              />
            </div>
            <div>
              <label className="ot-label-condensed text-[11px]">
                Descripción
              </label>
              <textarea
                className="mt-2 w-full border border-black/15 px-3 py-2.5 text-sm min-h-[100px]"
                value={description}
                onChange={(e) => setDescription(e.target.value)}
              />
            </div>
            <div className="grid grid-cols-2 gap-3">
              <div>
                <label className="ot-label-condensed text-[11px]">
                  Precio (COP)
                </label>
                <input
                  type="text"
                  inputMode="numeric"
                  className="mt-2 w-full border border-black/15 px-3 py-2.5 text-sm tabular-nums"
                  value={formatCopInput(price)}
                  onChange={(e) => setPrice(parseCopInput(e.target.value))}
                  placeholder="0"
                />
              </div>
              {mode === "create" && (
                <div>
                  <label className="ot-label-condensed text-[11px]">
                    Stock inicial / variante
                  </label>
                  <input
                    type="number"
                    className="mt-2 w-full border border-black/15 px-3 py-2.5 text-sm"
                    value={stockQty}
                    onChange={(e) => setStockQty(Number(e.target.value) || 0)}
                  />
                </div>
              )}
            </div>
          </div>
        )}

        {step === 3 && (
          <div className="space-y-5">
            <div className="border border-black/10 bg-ot-cream-dark/40 p-4 space-y-3">
              <div>
                <p className="ot-label-condensed text-[11px] text-ot-muted">
                  Paleta OT
                </p>
                <p className="mt-1 text-sm text-ot-muted">
                  Toca un color para añadirlo. Luego sube las fotos de esa
                  variante.
                </p>
              </div>
              <div className="flex flex-wrap gap-2.5">
                {OT_COLOR_PRESETS.map((preset) => {
                  const already = colorWays.some(
                    (c) =>
                      c.name.trim().toLowerCase() ===
                      preset.name.trim().toLowerCase()
                  );
                  return (
                    <button
                      key={preset.name}
                      type="button"
                      disabled={already || busy}
                      title={
                        already
                          ? `${preset.name} ya está agregado`
                          : `Agregar ${preset.name}`
                      }
                      onClick={() => {
                        setColorWays((prev) => {
                          const blankIdx = prev.findIndex(
                            (c) => !c.name.trim() && c.images.length === 0
                          );
                          const next: AdminColorWay = {
                            name: preset.name,
                            swatches: [...preset.swatches],
                            images: [],
                          };
                          if (blankIdx >= 0) {
                            return prev.map((c, i) =>
                              i === blankIdx ? next : c
                            );
                          }
                          return [...prev, next];
                        });
                        setError(null);
                      }}
                      className={`group flex flex-col items-center gap-1.5 w-[4.5rem] transition ${
                        already
                          ? "opacity-35 cursor-not-allowed"
                          : "hover:scale-[1.03] cursor-pointer"
                      }`}
                    >
                      <span
                        className="h-11 w-11 rounded-full border border-black/15 shadow-sm ring-offset-2 ring-offset-[var(--ot-cream,#f3efe5)] group-hover:ring-2 group-hover:ring-ot-ink"
                        style={{
                          background: `linear-gradient(135deg, ${preset.swatches[0]} 0 50%, ${preset.swatches[1]} 50% 100%)`,
                        }}
                      />
                      <span className="text-[10px] leading-tight text-center text-ot-ink/80 line-clamp-2">
                        {preset.name}
                      </span>
                    </button>
                  );
                })}
              </div>
            </div>

            {colorWays.map((cw, idx) => (
              <div
                key={idx}
                className="bg-white border border-black/10 p-5 space-y-4"
              >
                <div className="flex items-center justify-between gap-2">
                  <p className="font-serif text-xl">Color {idx + 1}</p>
                  {colorWays.length > 1 && (
                    <button
                      type="button"
                      className="text-xs text-red-700 underline underline-offset-2"
                      onClick={() =>
                        setColorWays((prev) => prev.filter((_, i) => i !== idx))
                      }
                    >
                      Quitar
                    </button>
                  )}
                </div>

                <div>
                  <label className="ot-label-condensed text-[11px] text-ot-muted">
                    Nombre
                  </label>
                  <input
                    className="mt-2 w-full border border-black/15 px-3 py-2.5 text-sm"
                    placeholder="O elige de la paleta OT arriba"
                    value={cw.name}
                    onChange={(e) =>
                      setColorWays((prev) =>
                        prev.map((c, i) =>
                          i === idx ? { ...c, name: e.target.value } : c
                        )
                      )
                    }
                  />
                </div>

                <div className="space-y-2">
                  <div className="flex flex-wrap items-center gap-3">
                    <p className="ot-label-condensed text-[11px] text-ot-muted">
                      Bolita
                    </p>
                    <span
                      className="h-10 w-10 rounded-full border border-black/15 shrink-0"
                      style={{
                        background: `linear-gradient(135deg, ${cw.swatches[0]} 0 50%, ${cw.swatches[1]} 50% 100%)`,
                      }}
                      title="Vista previa"
                    />
                    <div className="flex items-center gap-2 text-xs text-ot-muted">
                      <label className="inline-flex items-center gap-1.5">
                        A
                        <input
                          type="color"
                          value={cw.swatches[0]}
                          onChange={(e) =>
                            setColorWays((prev) =>
                              prev.map((c, i) =>
                                i === idx
                                  ? {
                                      ...c,
                                      swatches: [e.target.value, c.swatches[1]],
                                    }
                                  : c
                              )
                            )
                          }
                          className="h-8 w-8 cursor-pointer border border-black/10 bg-transparent p-0"
                        />
                      </label>
                      <label className="inline-flex items-center gap-1.5">
                        B
                        <input
                          type="color"
                          value={cw.swatches[1]}
                          onChange={(e) =>
                            setColorWays((prev) =>
                              prev.map((c, i) =>
                                i === idx
                                  ? {
                                      ...c,
                                      swatches: [c.swatches[0], e.target.value],
                                    }
                                  : c
                              )
                            )
                          }
                          className="h-8 w-8 cursor-pointer border border-black/10 bg-transparent p-0"
                        />
                      </label>
                    </div>
                  </div>
                  <div className="grid sm:grid-cols-2 gap-3">
                    {([0, 1] as const).map((half) => (
                      <div key={half}>
                        <p className="text-[10px] tracking-[0.12em] uppercase text-ot-muted mb-1.5">
                          Mitad {half === 0 ? "A" : "B"}
                        </p>
                        <div className="flex flex-wrap gap-1.5">
                          {OT_SWATCH_PALETTE.map((hex) => {
                            const active =
                              cw.swatches[half].toUpperCase() ===
                              hex.toUpperCase();
                            return (
                              <button
                                key={`${half}-${hex}`}
                                type="button"
                                title={hex}
                                onClick={() =>
                                  setColorWays((prev) =>
                                    prev.map((c, i) => {
                                      if (i !== idx) return c;
                                      const next: [string, string] = [
                                        c.swatches[0],
                                        c.swatches[1],
                                      ];
                                      next[half] = hex;
                                      return { ...c, swatches: next };
                                    })
                                  )
                                }
                                className={`h-7 w-7 rounded-full border transition ${
                                  active
                                    ? "ring-2 ring-ot-ink ring-offset-1 border-ot-ink"
                                    : "border-black/15 hover:scale-110"
                                }`}
                                style={{ background: hex }}
                              />
                            );
                          })}
                        </div>
                      </div>
                    ))}
                  </div>
                </div>

                <div>
                  <label className="ot-label-condensed text-[11px]">
                    Fotos de este color
                  </label>
                  <input
                    type="file"
                    accept="image/*"
                    multiple
                    className="mt-2 block w-full text-sm"
                    onChange={async (e) => {
                      const files = Array.from(e.target.files || []);
                      if (!files.length) return;
                      setBusy(true);
                      try {
                        const urls: string[] = [];
                        for (const f of files) {
                          urls.push(
                            await uploadFile(f, cw.name || `color-${idx}`)
                          );
                        }
                        setColorWays((prev) =>
                          prev.map((c, i) =>
                            i === idx
                              ? { ...c, images: [...c.images, ...urls] }
                              : c
                          )
                        );
                      } catch (err) {
                        setError(
                          err instanceof Error ? err.message : "Error al subir"
                        );
                      } finally {
                        setBusy(false);
                        e.target.value = "";
                      }
                    }}
                  />
                  <div className="mt-3 flex flex-wrap gap-2">
                    {cw.images.map((src) => (
                      <div key={src} className="relative">
                        {/* eslint-disable-next-line @next/next/no-img-element */}
                        <img
                          src={src}
                          alt=""
                          className="h-20 w-16 object-cover border border-black/10 bg-ot-cream"
                        />
                        <button
                          type="button"
                          className="absolute -top-1 -right-1 h-5 w-5 bg-ot-ink text-ot-cream text-xs"
                          onClick={() =>
                            setColorWays((prev) =>
                              prev.map((c, i) =>
                                i === idx
                                  ? {
                                      ...c,
                                      images: c.images.filter((u) => u !== src),
                                    }
                                  : c
                              )
                            )
                          }
                        >
                          ×
                        </button>
                      </div>
                    ))}
                  </div>
                </div>
              </div>
            ))}
            <button
              type="button"
              className="ot-btn ot-btn-ghost"
              onClick={() => setColorWays((prev) => [...prev, emptyColor()])}
            >
              + Color personalizado
            </button>
          </div>
        )}

        {step === 4 && (
          <div className="bg-white border border-black/10 p-5 space-y-4">
            <p className="text-sm text-ot-muted">
              Ficha técnica (aparece en el acordeón Especificaciones del PDP).
            </p>
            {specs.map((s, idx) => (
              <div key={idx} className="grid grid-cols-2 gap-2">
                <input
                  className="border border-black/15 px-3 py-2 text-sm"
                  placeholder="Etiqueta"
                  value={s.label}
                  onChange={(e) =>
                    setSpecs((prev) =>
                      prev.map((row, i) =>
                        i === idx ? { ...row, label: e.target.value } : row
                      )
                    )
                  }
                />
                <input
                  className="border border-black/15 px-3 py-2 text-sm"
                  placeholder="Valor"
                  value={s.value}
                  onChange={(e) =>
                    setSpecs((prev) =>
                      prev.map((row, i) =>
                        i === idx ? { ...row, value: e.target.value } : row
                      )
                    )
                  }
                />
              </div>
            ))}
            <button
              type="button"
              className="text-sm underline"
              onClick={() =>
                setSpecs((prev) => [...prev, { label: "", value: "" }])
              }
            >
              + Fila
            </button>
            <div className="border-t border-black/10 pt-4 text-sm space-y-1">
              <p>
                <strong>{title || "Sin nombre"}</strong> · {catMeta.label}
              </p>
              <p>{formatCopAdmin(price)}</p>
              <p>
                {colorWays.filter((c) => c.name && c.images.length).length}{" "}
                color(es) · tallas {catMeta.sizes.join(", ")}
              </p>
            </div>
          </div>
        )}

        <div className="flex flex-wrap gap-3">
          {step > 1 && (
            <button
              type="button"
              className="ot-btn ot-btn-ghost"
              onClick={() => setStep((s) => s - 1)}
              disabled={busy}
            >
              Atrás
            </button>
          )}
          {step < 4 ? (
            <button
              type="button"
              className="ot-btn"
              onClick={() => {
                if (!canGoTo(step + 1)) {
                  setError(
                    step === 1
                      ? usingCustomCategory
                        ? "Escribe el nombre de la categoría y al menos una talla."
                        : "Elige una categoría."
                      : step === 2
                        ? "Completa nombre y precio."
                        : step === 3
                          ? "Agrega al menos un color con fotos."
                          : "Completa este paso."
                  );
                  return;
                }
                if (step === 1 && usingCustomCategory) {
                  const id = slugifyCategory(customCategoryName);
                  if (!id) {
                    setError("Nombre de categoría inválido.");
                    return;
                  }
                  setCategory(id);
                }
                setError(null);
                setStep((s) => s + 1);
              }}
              disabled={busy}
            >
              Continuar
            </button>
          ) : (
            <button
              type="button"
              className="ot-btn"
              onClick={publish}
              disabled={busy}
            >
              {busy
                ? "Guardando…"
                : mode === "create"
                  ? "Publicar en la tienda"
                  : "Guardar cambios"}
            </button>
          )}
        </div>
      </div>
    );
  }

  return (
    <div className="space-y-6">
      <div className="flex flex-wrap items-center gap-3">
        <p className="ot-eyebrow">Fase E</p>
        <StatusPill status="activo" />
      </div>
      <div className="flex flex-wrap items-end justify-between gap-4">
        <div>
          <h1 className="font-serif text-4xl">Productos y catálogo</h1>
          <p className="text-ot-muted mt-2 max-w-xl text-sm leading-relaxed">
            Crea, edita, oculta o elimina prendas. Las fotos y colores se
            guardan en el formato OT de la tienda.
          </p>
        </div>
        <button type="button" className="ot-btn" onClick={startCreate}>
          + Nuevo producto
        </button>
      </div>

      <div className="flex flex-wrap gap-3 items-center">
        <input
          className="border border-black/15 px-3 py-2 text-sm min-w-[220px] bg-white"
          placeholder="Buscar por nombre o handle…"
          value={query}
          onChange={(e) => setQuery(e.target.value)}
        />
        <button
          type="button"
          className="ot-btn ot-btn-ghost"
          onClick={() => void load()}
          disabled={loading}
        >
          {loading ? "Actualizando…" : "Actualizar"}
        </button>
        <span className="text-sm text-ot-muted">
          {filtered.length} producto(s)
        </span>
      </div>

      {success && (
        <p className="text-sm text-ot-green border border-ot-green/25 bg-ot-green/[0.04] px-3 py-2">
          {success}
        </p>
      )}

      {error && (
        <p className="text-sm text-red-700 border border-red-700/20 bg-red-700/[0.04] px-3 py-2">
          {error}
        </p>
      )}

      <div className="bg-white border border-black/10 divide-y divide-black/10">
        {filtered.map((p) => (
          <div
            key={p.id}
            className="flex flex-wrap gap-4 items-center p-4 hover:bg-ot-cream/40 transition"
          >
            {/* eslint-disable-next-line @next/next/no-img-element */}
            <img
              src={p.thumbnail || "/brand/ot-club-seal.png"}
              alt=""
              className="h-16 w-14 object-cover bg-ot-cream border border-black/5"
            />
            <div className="min-w-0 flex-1">
              <p className="font-serif text-lg leading-tight">{p.title}</p>
              <p className="text-xs text-ot-muted mt-0.5">
                {p.category} · {p.handle} · {p.variant_count} variantes
              </p>
              <p className="text-sm mt-1">{formatCopAdmin(p.price)}</p>
            </div>
            <span
              className={`text-[10px] tracking-[0.14em] uppercase px-2 py-1 border ${
                p.status === "published"
                  ? "border-ot-green text-ot-green"
                  : "border-ot-muted text-ot-muted"
              }`}
            >
              {p.status === "published" ? "Visible" : "Oculto"}
            </span>
            <div className="flex flex-wrap gap-2">
              <Link
                href={`/product/${p.handle}`}
                className="text-xs underline underline-offset-2"
                target="_blank"
              >
                Ver
              </Link>
              <button
                type="button"
                className="text-xs underline underline-offset-2"
                onClick={() => startEdit(p)}
              >
                Editar
              </button>
              <button
                type="button"
                className="text-xs underline underline-offset-2"
                onClick={() => void toggleStatus(p)}
              >
                {p.status === "published" ? "Ocultar" : "Publicar"}
              </button>
              <button
                type="button"
                className="text-xs text-red-700 underline underline-offset-2"
                onClick={() => void remove(p)}
              >
                Eliminar
              </button>
            </div>
          </div>
        ))}
        {!loading && !filtered.length && (
          <p className="p-6 text-sm text-ot-muted">No hay productos.</p>
        )}
      </div>
    </div>
  );
}
