"use client";

import { useEffect, useMemo, useState } from "react";
import { useSearchParams } from "next/navigation";
import type { StoreProduct } from "@/lib/api";
import ProductCard from "./ProductCard";

type SortKey = "featured" | "price-asc" | "price-desc" | "name-asc";

const PAGE_SIZE = 8;

function uniqueValues(products: StoreProduct[], pick: (p: StoreProduct) => string | null): string[] {
  return Array.from(new Set(products.map(pick).filter((v): v is string => !!v))).sort();
}

/** Client-side filterable/sortable/paginated product grid — the "ALL GOODS" / "THE FULL
 *  INDEX" screen. The catalog is small (~30 SKUs), so all filtering happens in the browser
 *  over the already-fetched catalog rather than round-tripping server-side filter params.
 *  Initial filter values can be pre-applied via query params (?outfit=, ?gender=, ?category=,
 *  ?fabric=, ?age=) — used by /collections tiles that link into a pre-filtered shop view. */
export default function ShopGrid({ products }: { products: StoreProduct[] }) {
  const searchParams = useSearchParams();

  const [category, setCategory] = useState(searchParams.get("category") || "");
  const [fabric, setFabric] = useState(searchParams.get("fabric") || "");
  const [outfit, setOutfit] = useState(searchParams.get("outfit") || "");
  const [gender, setGender] = useState(searchParams.get("gender") || "");
  const [age, setAge] = useState(searchParams.get("age") || "");
  const [sort, setSort] = useState<SortKey>("featured");
  const [page, setPage] = useState(1);

  const categories = useMemo(() => uniqueValues(products, (p) => p.category), [products]);
  const fabrics = useMemo(() => uniqueValues(products, (p) => p.fabric), [products]);
  const outfits = useMemo(() => uniqueValues(products, (p) => p.outfitKey), [products]);
  const genders = useMemo(() => uniqueValues(products, (p) => p.gender), [products]);
  const ages = useMemo(() => uniqueValues(products, (p) => p.ageGroup), [products]);

  const filtered = useMemo(() => {
    let list = products.filter((p) => {
      if (category && p.category !== category) return false;
      if (fabric && p.fabric !== fabric) return false;
      if (outfit && p.outfitKey !== outfit) return false;
      if (gender && p.gender !== gender) return false;
      if (age && p.ageGroup !== age) return false;
      return true;
    });

    list = [...list];
    if (sort === "price-asc") list.sort((a, b) => a.basePrice - b.basePrice);
    else if (sort === "price-desc") list.sort((a, b) => b.basePrice - a.basePrice);
    else if (sort === "name-asc") list.sort((a, b) => a.name.localeCompare(b.name));

    return list;
  }, [products, category, fabric, outfit, gender, age, sort]);

  useEffect(() => setPage(1), [category, fabric, outfit, gender, age, sort]);

  const pageCount = Math.max(1, Math.ceil(filtered.length / PAGE_SIZE));
  const currentPage = Math.min(page, pageCount);
  const paged = filtered.slice((currentPage - 1) * PAGE_SIZE, currentPage * PAGE_SIZE);

  return (
    <div>
      <div className="flex flex-wrap items-end justify-between gap-6 pb-8">
        <div>
          <p className="text-[11px] font-bold uppercase tracking-[0.15em] text-[#b08968]">Collections / Filtered</p>
          <h1 className="mt-2 font-black uppercase leading-[0.92] tracking-tight text-[#1d2739] text-4xl sm:text-5xl lg:text-6xl">
            The Full Index
          </h1>
        </div>
        <div className="flex flex-col items-end gap-3">
          <p className="text-[11px] font-semibold uppercase tracking-wide text-[#6f7885]">
            Everything, {products.length} products — {filtered.length} items
          </p>
          {pageCount > 1 ? (
            <div className="flex items-center gap-2">
              {Array.from({ length: pageCount }, (_, i) => i + 1).map((n) => (
                <button
                  key={n}
                  onClick={() => setPage(n)}
                  className={`h-8 w-8 text-sm font-bold border ${
                    n === currentPage
                      ? "bg-[#1d2739] text-white border-[#1d2739]"
                      : "border-[rgba(29,39,57,0.25)] text-[#1d2739] hover:border-[#1d2739]"
                  }`}
                >
                  {n}
                </button>
              ))}
            </div>
          ) : null}
        </div>
      </div>

      <div className="flex flex-wrap items-center gap-3 border-y border-[rgba(29,39,57,0.18)] py-4">
        <span className="text-[11px] font-bold uppercase tracking-[0.15em] text-[#1d2739] mr-2">Refine</span>
        <Select label="Type" value={category} onChange={setCategory} options={categories} />
        <Select label="Fabric" value={fabric} onChange={setFabric} options={fabrics} />
        <Select label="Outfit" value={outfit} onChange={setOutfit} options={outfits} />
        <Select label="Gender" value={gender} onChange={setGender} options={genders} />
        <Select label="Age" value={age} onChange={setAge} options={ages} />
        <div className="ml-auto">
          <Select
            label="Sort"
            value={sort}
            onChange={(v) => setSort(v as SortKey)}
            options={["featured", "price-asc", "price-desc", "name-asc"]}
            optionLabels={{
              featured: "Featured",
              "price-asc": "Price: Low to High",
              "price-desc": "Price: High to Low",
              "name-asc": "Name: A to Z"
            }}
            allowEmpty={false}
          />
        </div>
      </div>

      {paged.length === 0 ? (
        <p className="mt-12 text-center text-sm text-[#6f7885]">No products match those filters.</p>
      ) : (
        <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 divide-x divide-y divide-[rgba(29,39,57,0.18)] border-b border-[rgba(29,39,57,0.18)]">
          {paged.map((p, i) => (
            <div key={p.slug} className="px-4 py-2">
              <ProductCard product={p} index={(currentPage - 1) * PAGE_SIZE + i + 1} />
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

function Select({
  label,
  value,
  onChange,
  options,
  optionLabels,
  allowEmpty = true
}: {
  label: string;
  value: string;
  onChange: (v: string) => void;
  options: string[];
  optionLabels?: Record<string, string>;
  allowEmpty?: boolean;
}) {
  if (options.length === 0 && allowEmpty) return null;
  return (
    <label className="relative inline-flex">
      <span className="sr-only">{label}</span>
      <select
        value={value}
        onChange={(e) => onChange(e.target.value)}
        className="appearance-none border border-[rgba(29,39,57,0.25)] bg-white pl-3 pr-7 py-2 text-[11px] font-semibold uppercase tracking-wide text-[#1d2739] focus:outline-none focus:border-[#b08968]"
      >
        {allowEmpty ? <option value="">All {label}</option> : null}
        {options.map((o) => (
          <option key={o} value={o}>
            {optionLabels?.[o] || o}
          </option>
        ))}
      </select>
      <svg
        className="pointer-events-none absolute right-2 top-1/2 -translate-y-1/2 h-3 w-3 text-[#6f7885]"
        viewBox="0 0 24 24"
        fill="none"
        stroke="currentColor"
        strokeWidth={2}
      >
        <path strokeLinecap="round" strokeLinejoin="round" d="M6 9l6 6 6-6" />
      </svg>
    </label>
  );
}
