"use client";

import { useMemo, useState } from "react";
import { Product } from "@/lib/types";
import { ProductGrid } from "./ProductGrid";
import { formatPrice } from "@/lib/format";

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

function FilterFields({
  brands,
  selectedBrands,
  toggleBrand,
  maxPrice,
  priceCeiling,
  setMaxPrice,
  inStockOnly,
  setInStockOnly,
  discountOnly,
  setDiscountOnly,
  onClear,
  idPrefix,
}: {
  brands: string[];
  selectedBrands: string[];
  toggleBrand: (b: string) => void;
  maxPrice: number;
  priceCeiling: number;
  setMaxPrice: (n: number) => void;
  inStockOnly: boolean;
  setInStockOnly: (v: boolean) => void;
  discountOnly: boolean;
  setDiscountOnly: (v: boolean) => void;
  onClear: () => void;
  idPrefix: string;
}) {
  return (
    <div className="flex flex-col gap-6">
      <div>
        <p className="text-sm font-semibold text-brand-ink">Brand</p>
        <div className="mt-3 flex flex-col gap-2.5">
          {brands.map((b) => (
            <label key={b} className="flex items-center gap-2.5 text-sm text-black/70">
              <input
                type="checkbox"
                checked={selectedBrands.includes(b)}
                onChange={() => toggleBrand(b)}
                className="h-4 w-4 rounded border-black/25 text-brand-orange focus:ring-brand-orange"
                id={`${idPrefix}-brand-${b}`}
              />
              {b}
            </label>
          ))}
        </div>
      </div>

      <div>
        <div className="flex items-center justify-between">
          <p className="text-sm font-semibold text-brand-ink">Max price</p>
          <span className="text-sm text-black/55">{formatPrice(maxPrice)}</span>
        </div>
        <input
          type="range"
          min={0}
          max={priceCeiling}
          step={Math.max(500, Math.round(priceCeiling / 100))}
          value={maxPrice}
          onChange={(e) => setMaxPrice(Number(e.target.value))}
          className="mt-3 w-full accent-brand-orange"
          id={`${idPrefix}-price`}
        />
      </div>

      <div className="flex flex-col gap-2.5">
        <label className="flex items-center gap-2.5 text-sm text-black/70">
          <input
            type="checkbox"
            checked={inStockOnly}
            onChange={(e) => setInStockOnly(e.target.checked)}
            className="h-4 w-4 rounded border-black/25 text-brand-orange focus:ring-brand-orange"
          />
          In stock only
        </label>
        <label className="flex items-center gap-2.5 text-sm text-black/70">
          <input
            type="checkbox"
            checked={discountOnly}
            onChange={(e) => setDiscountOnly(e.target.checked)}
            className="h-4 w-4 rounded border-black/25 text-brand-orange focus:ring-brand-orange"
          />
          On sale
        </label>
      </div>

      <button
        type="button"
        onClick={onClear}
        className="self-start text-sm font-medium text-brand-orange-dark hover:underline"
      >
        Clear filters
      </button>
    </div>
  );
}

export function CategoryBrowser({ products }: { products: Product[] }) {
  const brands = useMemo(
    () => Array.from(new Set(products.map((p) => p.brand))).sort(),
    [products]
  );
  const priceCeiling = useMemo(
    () => Math.max(...products.map((p) => p.price), 1000),
    [products]
  );

  const [selectedBrands, setSelectedBrands] = useState<string[]>([]);
  const [maxPrice, setMaxPrice] = useState(priceCeiling);
  const [inStockOnly, setInStockOnly] = useState(false);
  const [discountOnly, setDiscountOnly] = useState(false);
  const [sort, setSort] = useState<SortKey>("featured");
  const [drawerOpen, setDrawerOpen] = useState(false);

  const toggleBrand = (b: string) =>
    setSelectedBrands((prev) =>
      prev.includes(b) ? prev.filter((x) => x !== b) : [...prev, b]
    );

  const clear = () => {
    setSelectedBrands([]);
    setMaxPrice(priceCeiling);
    setInStockOnly(false);
    setDiscountOnly(false);
  };

  const activeCount =
    selectedBrands.length +
    (maxPrice < priceCeiling ? 1 : 0) +
    (inStockOnly ? 1 : 0) +
    (discountOnly ? 1 : 0);

  const filtered = useMemo(() => {
    let list = products.filter((p) => {
      if (selectedBrands.length > 0 && !selectedBrands.includes(p.brand)) return false;
      if (p.price > maxPrice) return false;
      if (inStockOnly && p.stock <= 0) return false;
      if (discountOnly && !(p.compareAtPrice && p.compareAtPrice > p.price)) return false;
      return true;
    });
    if (sort === "price-asc") list = [...list].sort((a, b) => a.price - b.price);
    if (sort === "price-desc") list = [...list].sort((a, b) => b.price - a.price);
    if (sort === "newest")
      list = [...list].sort((a, b) => (a.createdAt < b.createdAt ? 1 : -1));
    if (sort === "featured")
      list = [...list].sort((a, b) => Number(b.featured) - Number(a.featured));
    return list;
  }, [products, selectedBrands, maxPrice, inStockOnly, discountOnly, sort]);

  const filterProps = {
    brands,
    selectedBrands,
    toggleBrand,
    maxPrice,
    priceCeiling,
    setMaxPrice,
    inStockOnly,
    setInStockOnly,
    discountOnly,
    setDiscountOnly,
    onClear: clear,
  };

  return (
    <div className="lg:grid lg:grid-cols-[220px_1fr] lg:gap-8">
      <aside className="hidden lg:block">
        <FilterFields {...filterProps} idPrefix="desktop" />
      </aside>

      <div>
        <div className="mb-5 flex items-center justify-between gap-3">
          <button
            type="button"
            onClick={() => setDrawerOpen(true)}
            className="flex items-center gap-1.5 rounded-lg border border-black/10 px-3.5 py-2 text-sm font-medium text-brand-ink lg:hidden"
          >
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2}>
              <path strokeLinecap="round" strokeLinejoin="round" d="M4 6h16M7 12h10M10 18h4" />
            </svg>
            Filters {activeCount > 0 && `(${activeCount})`}
          </button>
          <p className="hidden text-sm text-black/50 lg:block">
            {filtered.length} product{filtered.length === 1 ? "" : "s"}
          </p>
          <select
            value={sort}
            onChange={(e) => setSort(e.target.value as SortKey)}
            className="ml-auto rounded-lg border border-black/10 bg-white px-3 py-2 text-sm text-brand-ink focus:border-brand-orange focus:outline-none"
            aria-label="Sort products"
          >
            <option value="featured">Featured</option>
            <option value="newest">Newest</option>
            <option value="price-asc">Price: Low to High</option>
            <option value="price-desc">Price: High to Low</option>
          </select>
        </div>

        <ProductGrid
          products={filtered}
          emptyTitle="No products match your filters"
          emptyDescription="Try clearing a filter or two."
        />
      </div>

      {drawerOpen && (
        <div className="fixed inset-0 z-[60] lg:hidden" role="dialog" aria-modal="true">
          <button
            aria-label="Close filters"
            onClick={() => setDrawerOpen(false)}
            className="absolute inset-0 bg-black/40"
          />
          <div className="absolute bottom-0 left-0 right-0 max-h-[85vh] overflow-auto rounded-t-2xl bg-white p-5">
            <div className="mb-4 flex items-center justify-between">
              <p className="font-display text-lg font-semibold text-brand-ink">Filters</p>
              <button
                aria-label="Close filters"
                onClick={() => setDrawerOpen(false)}
                className="rounded-full p-1.5 text-black/50 hover:bg-black/5"
              >
                <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2}>
                  <path strokeLinecap="round" d="M6 6l12 12M18 6L6 18" />
                </svg>
              </button>
            </div>
            <FilterFields {...filterProps} idPrefix="mobile" />
            <button
              type="button"
              onClick={() => setDrawerOpen(false)}
              className="mt-6 w-full rounded-lg bg-brand-ink py-3 text-sm font-semibold text-white"
            >
              Show {filtered.length} result{filtered.length === 1 ? "" : "s"}
            </button>
          </div>
        </div>
      )}
    </div>
  );
}
