"use client";

import { useEffect, useMemo, useState } from "react";
import type { Product } from "@/data/products";
import { formatCop } from "@/data/products";
import { useCart } from "@/context/CartContext";
import { useFavorites } from "@/context/FavoritesContext";
import { Heart } from "lucide-react";
import { ImageSlider } from "@/components/ui/ImageSlider";
import { colorToHex } from "@/lib/colors";
import {
  enrichProductWithEditorial,
  getColorWays,
  getProductTechHeading,
  getProductTechSpecs,
  type ColorWay,
} from "@/lib/product-galleries";
import {
  SKIRT_OPTIONS,
  productNeedsSkirt,
  type SkirtOptionId,
} from "@/lib/skirt-options";
import { SpecsAccordion } from "@/components/product/SpecsAccordion";

function variantStock(
  product: Product,
  size: string,
  color: string
): { exists: boolean; inStock: boolean; qty: number | null } {
  if (!product.variants?.length) {
    return { exists: true, inStock: true, qty: null };
  }
  const exact = product.variants.find((v) => v.size === size && v.color === color);
  if (exact) {
    if (!exact.manage_inventory) return { exists: true, inStock: true, qty: null };
    const qty =
      typeof exact.inventory_quantity === "number" ? exact.inventory_quantity : 0;
    return { exists: true, inStock: qty > 0, qty };
  }

  const couple = size.match(/^Dama\s+(\S+)\s+·\s+Caballero\s+(\S+)$/i);
  if (couple) {
    const [, dama, cab] = couple;
    const dual = product.variants.find(
      (v) =>
        v.sizeDama === dama &&
        v.sizeCaballero === cab &&
        v.color === color
    );
    if (dual) {
      if (!dual.manage_inventory) return { exists: true, inStock: true, qty: null };
      const qty =
        typeof dual.inventory_quantity === "number" ? dual.inventory_quantity : 0;
      return { exists: true, inStock: qty > 0, qty };
    }
    return { exists: false, inStock: false, qty: 0 };
  }

  const key = color.toLowerCase().split("&")[0].trim().slice(0, 8);
  const fuzzy = product.variants.find(
    (v) =>
      v.size === size &&
      v.color.toLowerCase().includes(key.split(" ")[0] || key)
  );
  if (!fuzzy) return { exists: true, inStock: true, qty: null };
  if (!fuzzy.manage_inventory) return { exists: true, inStock: true, qty: null };
  const qty =
    typeof fuzzy.inventory_quantity === "number" ? fuzzy.inventory_quantity : 0;
  return { exists: true, inStock: qty > 0, qty };
}

function ColorComboSwatch({
  way,
  selected,
  disabled,
  onSelect,
}: {
  way: ColorWay;
  selected: boolean;
  disabled?: boolean;
  onSelect: () => void;
}) {
  // Siempre diagonal de 2 colores (como Mujer)
  const c1 = way.swatches[0] || "#ccc";
  const c2 = way.swatches[1] || c1;

  const isAccentLight = (hex: string) => {
    const u = hex.toUpperCase();
    return (
      u === "#FFFFFF" ||
      u === "#FFF" ||
      u === "#F5F5F5" ||
      u === "#F3EFE5" ||
      u === "#F2EFE9"
    );
  };

  const topLeft = isAccentLight(c1) && !isAccentLight(c2) ? c2 : c1;
  const bottomRight = isAccentLight(c1) && !isAccentLight(c2) ? c1 : c2;

  const hasLight = [c1, c2].some(
    (h) =>
      isAccentLight(h) ||
      h.toUpperCase() === "#C4B59A" ||
      h.toUpperCase() === "#9CAF88"
  );

  return (
    <button
      type="button"
      onClick={onSelect}
      aria-label={way.name}
      aria-pressed={selected}
      title={way.name}
      disabled={disabled}
      className={`relative h-11 w-11 shrink-0 rounded-full transition ${
        disabled ? "opacity-40 cursor-not-allowed" : "cursor-pointer hover:scale-105"
      } ${
        selected
          ? "ring-2 ring-ot-ink ring-offset-2 ring-offset-[var(--ot-cream,#f3efe5)]"
          : hasLight
            ? "ring-1 ring-black/15"
            : "ring-1 ring-black/10"
      }`}
      style={{
        background: `linear-gradient(135deg, ${topLeft} 0 50%, ${bottomRight} 50% 100%)`,
      }}
    />
  );
}

export function ProductDetail({ product: raw }: { product: Product }) {
  const product = useMemo(() => enrichProductWithEditorial(raw), [raw]);
  const colorWays = useMemo(() => getColorWays(product), [product]);
  const techSpecs = useMemo(
    () => getProductTechSpecs(product),
    [product.slug]
  );
  const techHeading = useMemo(
    () => getProductTechHeading(product.slug),
    [product.slug]
  );
  const { addItem, adding } = useCart();
  const { isFavorite, toggle: toggleFavorite } = useFavorites();
  const liked = isFavorite(product.id) || isFavorite(product.slug);
  const needsSkirt = productNeedsSkirt(product.slug);
  const isCoupleSet = product.slug === "set-pareja-club-1976";
  const sizesDama = product.sizesDama || ["XS", "S", "M", "L"];
  const sizesCaballero = product.sizesCaballero || product.sizes;
  const [size, setSize] = useState(product.sizes[0] || "");
  const [sizeDama, setSizeDama] = useState(sizesDama[0] || "S");
  const [sizeCaballero, setSizeCaballero] = useState(sizesCaballero[0] || "M");
  const [color, setColor] = useState(product.colors[0] || "");
  const [skirt, setSkirt] = useState<SkirtOptionId | "">("");
  const [added, setAdded] = useState(false);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    setColor(product.colors[0] || "");
    setSize(product.sizes[0] || "");
    setSizeDama((product.sizesDama || ["XS", "S", "M", "L"])[0] || "S");
    setSizeCaballero(
      (product.sizesCaballero || product.sizes)[0] || "M"
    );
    setSkirt("");
  }, [product.slug, product.colors, product.sizes, product.sizesDama, product.sizesCaballero]);

  const activeWay = useMemo(() => {
    if (!colorWays) return null;
    return colorWays.find((w) => w.name === color) || colorWays[0];
  }, [colorWays, color]);

  const ways = useMemo(
    () =>
      colorWays ||
      product.colors.map(
        (name): ColorWay => ({
          name,
          tagline: "",
          swatches: [colorToHex(name)],
          slides: [],
        })
      ),
    [colorWays, product.colors]
  );

  const slides = useMemo(() => {
    if (activeWay) return activeWay.slides;
    return product.images.map((src) => ({ src }));
  }, [activeWay, product.images]);

  const coupleSizeKey = useMemo(
    () => `Dama ${sizeDama} · Caballero ${sizeCaballero}`,
    [sizeDama, sizeCaballero]
  );

  const activeSize = isCoupleSet ? coupleSizeKey : size;

  const stock = useMemo(
    () => variantStock(product, activeSize, color),
    [product, activeSize, color]
  );

  const onAdd = async () => {
    if (adding) return;
    if (!color || !activeSize) {
      setError(
        isCoupleSet
          ? "Elige color y tallas de dama y caballero."
          : "Elige un color y una talla para agregar."
      );
      return;
    }
    if (!stock.exists) {
      setError("Esa combinación de talla y color no está disponible.");
      return;
    }
    if (!stock.inStock) {
      setError("Esa talla y color están agotados.");
      return;
    }
    setError(null);
    try {
      await addItem(product, {
        size: activeSize,
        color,
        ...(needsSkirt && skirt ? { skirt } : {}),
      });
      setAdded(true);
      setTimeout(() => setAdded(false), 1800);
    } catch (err) {
      setError(err instanceof Error ? err.message : "No se pudo agregar.");
    }
  };

  return (
    <div className="ot-container py-4 md:py-6">
      <div className="grid lg:grid-cols-2 gap-5 lg:gap-8 lg:items-start">
        <ImageSlider slides={slides} alt={product.name} resetKey={color} />

        <div className="relative z-10 max-w-xl min-w-0">
          <p className="ot-label-condensed text-ot-muted">
            {product.collection}
            {product.collection.toLowerCase().includes("club")
              ? ""
              : " — Club 1976"}
          </p>

          <div className="mt-1.5 flex items-start justify-between gap-3">
            <h1
              className="text-[1.85rem] sm:text-[2.15rem] md:text-[2.65rem] leading-[1.05] tracking-tight text-ot-ink min-w-0"
              style={{ fontFamily: "var(--font-fraunces), Fraunces, Georgia, serif" }}
            >
              {product.name}
            </h1>
            <button
              type="button"
              onClick={() => toggleFavorite(product)}
              aria-label={liked ? "Quitar de favoritos" : "Guardar en favoritos"}
              aria-pressed={liked}
              title={liked ? "Quitar de favoritos" : "Me gusta · guardar en favoritos"}
              className={`mt-1 shrink-0 p-1.5 transition ${
                liked
                  ? "text-ot-green"
                  : "text-ot-ink/45 hover:text-ot-green"
              }`}
            >
              <Heart
                size={22}
                strokeWidth={1.6}
                fill={liked ? "currentColor" : "none"}
              />
            </button>
          </div>

          <p className="ot-label-condensed mt-2 text-ot-muted">
            {product.slug === "bermuda-y-camisa" ||
            product.slug === "polos-hombre" ||
            product.slug === "conjunto-dos-piezas-chaqueta"
              ? "Clásico · Masculino · Elegancia con carácter"
              : product.slug === "set-completo-club-1976"
                ? "Clásico · Femenino · Club 1976"
                : product.slug === "set-pareja-club-1976"
                  ? "Match en la cancha · Club 1976"
                  : product.category === "accesorios"
                    ? "Detalle · Firma OT · Club 1976"
                    : product.category === "hombre"
                      ? "Clásico · Masculino · Atemporal"
                      : "Clásico · Femenino · Atemporal"}
          </p>
          {product.category === "hombre" ? (
            <span
              className="mt-2.5 mb-0.5 block h-[2px] w-28 max-w-full"
              style={{
                background:
                  "linear-gradient(90deg, #1A237E 0 33.33%, #C8C8C8 33.33% 66.66%, #B71C1C 66.66% 100%)",
              }}
              aria-hidden
            />
          ) : null}

          <p
            className="mt-3 text-[1.35rem] md:text-[1.6rem] tracking-wide text-ot-ink"
            style={{ fontFamily: "var(--font-fraunces), Fraunces, Georgia, serif" }}
          >
            {formatCop(product.price)}
          </p>

          <div className="mt-5">
            <div className="flex items-baseline justify-between gap-3 mb-2.5">
              <p className="ot-label-condensed text-ot-ink">Color</p>
              {color ? (
                <p
                  className="text-[0.85rem] sm:text-[0.95rem] text-ot-ink/90 text-right leading-snug max-w-[65%]"
                  style={{ fontFamily: "var(--font-fraunces), Fraunces, Georgia, serif" }}
                >
                  {color}
                </p>
              ) : null}
            </div>

            <div
              className="flex flex-wrap gap-2.5 sm:gap-3.5"
              role="listbox"
              aria-label="Colores disponibles"
            >
              {ways.map((way) => {
                const selected = color === way.name;
                const colorStock = variantStock(product, activeSize, way.name);
                const disabled = colorStock.exists && !colorStock.inStock;
                return (
                  <ColorComboSwatch
                    key={way.name}
                    way={way}
                    selected={selected}
                    disabled={disabled}
                    onSelect={() => {
                      setColor(way.name);
                      setError(null);
                    }}
                  />
                );
              })}
            </div>

            {activeWay?.tagline ? (
              <p
                className="mt-3 italic text-[0.98rem] sm:text-[1.05rem] text-ot-ink/70 leading-snug"
                style={{ fontFamily: "var(--font-fraunces), Fraunces, Georgia, serif" }}
              >
                “{activeWay.tagline.replace(/^["“]|["”]$/g, "")}”
              </p>
            ) : null}
          </div>

          <div className="ot-rule mt-5 mb-5" />

          <p
            className="w-full text-[1.05rem] sm:text-[1.12rem] md:text-[1.18rem] leading-[1.3] text-ot-ink/85"
            style={{
              fontFamily:
                "var(--font-cormorant), 'Cormorant Garamond', Garamond, Georgia, serif",
              fontWeight: 500,
            }}
          >
            {product.description}
          </p>

          {isCoupleSet ? (
            <>
              <div className="mt-5">
                <div className="mb-2.5">
                  <p className="ot-label-condensed text-ot-ink">Talla dama</p>
                </div>
                <div className="flex flex-wrap gap-2.5">
                  {sizesDama.map((s) => {
                    const selected = sizeDama === s;
                    const key = `Dama ${s} · Caballero ${sizeCaballero}`;
                    const sizeStock = variantStock(product, key, color);
                    const disabled = sizeStock.exists && !sizeStock.inStock;
                    return (
                      <button
                        key={`dama-${s}`}
                        type="button"
                        onClick={() => {
                          setSizeDama(s);
                          setError(null);
                        }}
                        aria-pressed={selected}
                        className={`w-12 h-12 border text-sm cursor-pointer transition ot-label-condensed tracking-[0.08em] ${
                          selected
                            ? "border-ot-ink bg-ot-ink text-ot-cream"
                            : disabled
                              ? "border-black/10 bg-black/5 text-ot-muted line-through"
                              : "border-black/25 bg-transparent hover:border-ot-ink"
                        }`}
                      >
                        {s}
                      </button>
                    );
                  })}
                </div>
              </div>
              <div className="mt-5">
                <div className="mb-2.5">
                  <p className="ot-label-condensed text-ot-ink">
                    Talla caballero
                  </p>
                </div>
                <div className="flex flex-wrap gap-2.5">
                  {sizesCaballero.map((s) => {
                    const selected = sizeCaballero === s;
                    const key = `Dama ${sizeDama} · Caballero ${s}`;
                    const sizeStock = variantStock(product, key, color);
                    const disabled = sizeStock.exists && !sizeStock.inStock;
                    return (
                      <button
                        key={`cab-${s}`}
                        type="button"
                        onClick={() => {
                          setSizeCaballero(s);
                          setError(null);
                        }}
                        aria-pressed={selected}
                        className={`w-12 h-12 border text-sm cursor-pointer transition ot-label-condensed tracking-[0.08em] ${
                          selected
                            ? "border-ot-ink bg-ot-ink text-ot-cream"
                            : disabled
                              ? "border-black/10 bg-black/5 text-ot-muted line-through"
                              : "border-black/25 bg-transparent hover:border-ot-ink"
                        }`}
                      >
                        {s}
                      </button>
                    );
                  })}
                </div>
              </div>
            </>
          ) : (
            <div className="mt-5">
              <div className="mb-2.5">
                <p className="ot-label-condensed text-ot-ink">Talla</p>
              </div>
              <div className="flex flex-wrap gap-2.5">
                {product.sizes.map((s) => {
                  const selected = size === s;
                  const sizeStock = variantStock(product, s, color);
                  const disabled = sizeStock.exists && !sizeStock.inStock;
                  return (
                    <button
                      key={s}
                      type="button"
                      onClick={() => {
                        setSize(s);
                        setError(null);
                      }}
                      aria-pressed={selected}
                      className={`w-12 h-12 border text-sm cursor-pointer transition ot-label-condensed tracking-[0.08em] ${
                        selected
                          ? "border-ot-ink bg-ot-ink text-ot-cream"
                          : disabled
                            ? "border-black/10 bg-black/5 text-ot-muted line-through"
                            : "border-black/25 bg-transparent hover:border-ot-ink"
                      }`}
                    >
                      {s}
                    </button>
                  );
                })}
              </div>
            </div>
          )}

          {needsSkirt ? (
            <div className="mt-5">
              <div className="mb-2.5">
                <p className="ot-label-condensed text-ot-ink">Tipo de falda</p>
                <p
                  className="mt-2 text-[0.88rem] sm:text-[1.05rem] leading-snug font-bold text-ot-ink"
                  style={{
                    fontFamily:
                      "var(--font-fraunces), Fraunces, Georgia, serif",
                  }}
                >
                  Opcional. Si no eliges ninguna, te llega el modelo original
                  de la foto.
                </p>
              </div>
              <div
                className="flex flex-col gap-2.5 sm:gap-3"
                role="listbox"
                aria-label="Tipo de falda"
              >
                {[SKIRT_OPTIONS.slice(0, 4), SKIRT_OPTIONS.slice(4)].map(
                  (row, rowIdx) => (
                    <div
                      key={rowIdx}
                      className="grid grid-cols-4 gap-1.5 sm:gap-2.5"
                    >
                      {row.map((opt) => {
                        const selected = skirt === opt.id;
                        return (
                          <button
                            key={opt.id}
                            type="button"
                            onClick={() => {
                              setSkirt((prev) =>
                                prev === opt.id ? "" : opt.id
                              );
                              setError(null);
                            }}
                            aria-pressed={selected}
                            aria-label={opt.label}
                            title={opt.label}
                            className={`group relative block border bg-ot-cream cursor-pointer transition ${
                              selected
                                ? "border-ot-ink ring-2 ring-ot-ink ring-offset-1 ring-offset-[var(--ot-cream,#f3efe5)]"
                                : "border-black/15 hover:border-ot-ink"
                            }`}
                          >
                            <span className="relative block w-full overflow-hidden">
                              {/* eslint-disable-next-line @next/next/no-img-element */}
                              <img
                                src={opt.image}
                                alt={opt.label}
                                className="aspect-[3/4] w-full object-contain object-center bg-ot-cream p-0.5 sm:p-1"
                                draggable={false}
                              />
                              {selected ? (
                                <span
                                  className="absolute top-1 right-1 flex h-4 w-4 sm:h-5 sm:w-5 items-center justify-center rounded-full bg-ot-ink text-ot-cream shadow-sm"
                                  aria-hidden
                                >
                                  <svg
                                    viewBox="0 0 16 16"
                                    className="h-2.5 w-2.5 sm:h-3 sm:w-3"
                                    fill="none"
                                    stroke="currentColor"
                                    strokeWidth="2.4"
                                    strokeLinecap="round"
                                    strokeLinejoin="round"
                                  >
                                    <path d="M3.5 8.5 6.5 11.5 12.5 4.5" />
                                  </svg>
                                </span>
                              ) : null}
                            </span>
                          </button>
                        );
                      })}
                    </div>
                  )
                )}
              </div>
            </div>
          ) : null}

          {techSpecs ? (
            <SpecsAccordion items={techSpecs} heading={techHeading} />
          ) : null}

          <div className="mt-5 flex gap-2.5">
            <button
              type="button"
              className="ot-btn flex-1 cursor-pointer disabled:opacity-60"
              onClick={onAdd}
              disabled={adding || !stock.inStock || !stock.exists}
            >
              {adding
                ? "Agregando…"
                : added
                  ? "Agregado ✓"
                  : !stock.inStock
                    ? "Agotado"
                    : "Agregar al carrito"}
            </button>
            <button
              type="button"
              onClick={() => toggleFavorite(product)}
              aria-label={liked ? "Quitar de favoritos" : "Guardar en favoritos"}
              aria-pressed={liked}
              className={`shrink-0 border px-3.5 flex items-center justify-center transition ${
                liked
                  ? "border-ot-green bg-ot-green text-ot-cream"
                  : "border-black/20 bg-white text-ot-ink hover:border-ot-green"
              }`}
            >
              <Heart
                size={18}
                strokeWidth={1.7}
                fill={liked ? "currentColor" : "none"}
              />
            </button>
          </div>
          {error && (
            <p className="mt-2 text-sm text-red-700 text-center">{error}</p>
          )}
          {added && (
            <p className="mt-2 text-sm text-ot-green text-center">
              Listo. Ya está en tu carrito.
            </p>
          )}

          <p className="mt-3 text-sm text-ot-muted text-center">
            {stock.inStock
              ? "Disponible · Envío en 3–5 días hábiles"
              : "Agotado en esta talla y color"}
          </p>
        </div>
      </div>
    </div>
  );
}
