"use client";

import { SlidersHorizontal, X } from "lucide-react";
import { useEffect, useMemo, useState } from "react";
import { ProductCard } from "@/components/product/product-card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import type { Product } from "@/lib/headless/types";

type CatalogClientProps = {
  products: Product[];
  initialCategory?: string;
  initialCollection?: string;
  initialQuery?: string;
};

export function CatalogClient({
  products,
  initialCategory = "Todos",
  initialCollection = "",
  initialQuery = "",
}: CatalogClientProps) {
  const [query, setQuery] = useState(initialQuery);
  const [category, setCategory] = useState(initialCategory);
  const [collection, setCollection] = useState(initialCollection);
  const [brand, setBrand] = useState("Todas");
  const [age, setAge] = useState("Todas");
  const [sort, setSort] = useState("featured");

  const categories = ["Todos", ...new Set(products.map((product) => product.category))];
  const brands = ["Todas", ...new Set(products.map((product) => product.brand))];
  const ages = ["Todas", ...new Set(products.map((product) => product.ageRange))];
  const pricedProducts = products.filter((product) => product.price !== null);
  const maxCatalogPrice = pricedProducts.length
    ? Math.max(...pricedProducts.map((product) => product.price ?? 0))
    : 0;
  const [maxPrice, setMaxPrice] = useState(maxCatalogPrice);

  // Next.js conserva la instancia del componente cuando solo cambia el query string.
  // Sin esta sincronización, el catálogo anterior permanece visible hasta presionar F5.
  useEffect(() => {
    setQuery(initialQuery);
    setCategory(initialCategory || "Todos");
    setCollection(initialCollection || "");
    setBrand("Todas");
    setAge("Todas");
    setSort("featured");
    setMaxPrice(maxCatalogPrice);
  }, [initialCategory, initialCollection, initialQuery, maxCatalogPrice]);

  const filtered = useMemo(
    () =>
      products
        .filter((product) => {
          const search = [
            product.name,
            product.category,
            product.collection,
            product.brand,
          ]
            .join(" ")
            .toLowerCase();

          return (
            (!query || search.includes(query.toLowerCase())) &&
            (category === "Todos" || product.category === category) &&
            (!collection || product.collection === collection) &&
            (brand === "Todas" || product.brand === brand) &&
            (age === "Todas" || product.ageRange === age) &&
            (product.price === null || maxPrice === 0 || product.price <= maxPrice)
          );
        })
        .sort((a, b) =>
          sort === "name"
            ? a.name.localeCompare(b.name, "es")
            : sort === "new"
              ? Number(b.isNew) - Number(a.isNew)
              : Number(b.featured) - Number(a.featured),
        ),
    [age, brand, category, collection, maxPrice, products, query, sort],
  );

  const reset = () => {
    setQuery("");
    setCategory("Todos");
    setCollection("");
    setBrand("Todas");
    setAge("Todas");
    setMaxPrice(maxCatalogPrice);
    setSort("featured");
  };

  return (
    <div className="mx-auto max-w-7xl px-4 py-10">
      <div className="mb-8">
        <span className="text-xs font-black uppercase tracking-[.18em] text-fuchsia-600">
          Catálogo completo
        </span>
        <h1 className="mt-2 text-5xl font-black tracking-tight">Todos los tesoros</h1>
        <p className="mt-3 text-slate-500">
          Filtra por categoría, marca o edad sin recargar la página.
        </p>
      </div>

      <div className="grid gap-8 lg:grid-cols-[260px_1fr]">
        <aside className="h-fit space-y-6 rounded-3xl border border-slate-100 bg-white p-6 shadow-lg shadow-slate-900/5 lg:sticky lg:top-44">
          <div className="flex items-center justify-between">
            <strong className="flex items-center gap-2 text-lg font-black">
              <SlidersHorizontal className="size-5 text-cyan-600" />
              Filtros
            </strong>
            <button onClick={reset} className="text-xs font-black text-fuchsia-600">
              <X className="mr-1 inline size-3" />
              Limpiar
            </button>
          </div>

          <Input
            value={query}
            onChange={(event) => setQuery(event.target.value)}
            placeholder="Buscar…"
          />

          <Filter
            title="Categoría"
            values={categories}
            selected={category}
            onChange={setCategory}
          />
          <Filter title="Marca" values={brands} selected={brand} onChange={setBrand} />
          <Filter title="Edad" values={ages} selected={age} onChange={setAge} />

          <fieldset>
            <legend className="mb-3 text-sm font-black">Precio máximo</legend>
            {maxCatalogPrice > 0 ? (
              <>
                <input
                  aria-label="Precio máximo"
                  type="range"
                  min={0}
                  max={maxCatalogPrice}
                  step={5000}
                  value={maxPrice}
                  onChange={(event) => setMaxPrice(Number(event.target.value))}
                  className="w-full accent-fuchsia-500"
                />
                <p className="mt-2 text-xs font-bold text-slate-500">
                  Hasta ${maxPrice.toLocaleString("es-CO")}
                </p>
              </>
            ) : (
              <p className="rounded-2xl bg-yellow-50 p-3 text-xs font-bold leading-5 text-yellow-800">
                El filtro se activa automáticamente cuando el backend entregue precios.
              </p>
            )}
          </fieldset>
        </aside>

        <section>
          <div className="mb-5 flex items-center justify-between gap-4">
            <p className="text-sm font-bold text-slate-500">{filtered.length} productos</p>
            <select
              value={sort}
              onChange={(event) => setSort(event.target.value)}
              className="h-11 rounded-full border border-slate-200 bg-white px-4 text-sm font-bold"
            >
              <option value="featured">Destacados</option>
              <option value="new">Novedades</option>
              <option value="name">Nombre</option>
            </select>
          </div>

          {filtered.length ? (
            <div className="grid gap-5 sm:grid-cols-2 xl:grid-cols-3">
              {filtered.map((product) => (
                <ProductCard key={product.id} product={product} />
              ))}
            </div>
          ) : (
            <div className="grid min-h-80 place-items-center rounded-3xl border border-dashed border-slate-300 text-center">
              <div>
                <p className="text-xl font-black">No encontramos productos</p>
                <Button variant="magenta" className="mt-4" onClick={reset}>
                  Restablecer filtros
                </Button>
              </div>
            </div>
          )}
        </section>
      </div>
    </div>
  );
}

function Filter({
  title,
  values,
  selected,
  onChange,
}: {
  title: string;
  values: string[];
  selected: string;
  onChange: (value: string) => void;
}) {
  return (
    <fieldset>
      <legend className="mb-3 text-sm font-black">{title}</legend>
      <div className="flex flex-wrap gap-2">
        {values.map((value) => (
          <button
            type="button"
            key={value}
            onClick={() => onChange(value)}
            className={`rounded-full px-3 py-2 text-xs font-bold transition ${
              selected === value
                ? "bg-slate-950 text-white"
                : "bg-slate-100 text-slate-600 hover:bg-cyan-100"
            }`}
          >
            {value}
          </button>
        ))}
      </div>
    </fieldset>
  );
}
