// -----------------------------------------------------------------------------
// Food-Ka — Agrégateur de produits d'épicerie (province de Québec)
// Auteur : Simon-Pierre Boucher — contact@spboucher.ai
// pages/Home.tsx : accueil — héro, statistiques, filtres, grille de produits
//   Filtres : recherche, catégorie, bannière, marque, prix min/max, en solde,
//   tri — avec pastilles de filtres actifs et pagination « Charger plus ».
//   La même page sert la vue « Aubaines » (/aubaines), pré-filtrée en solde.
// -----------------------------------------------------------------------------
import { useEffect, useMemo, useState } from "react";
import { useSearchParams } from "react-router-dom";
import {
  Facets, Product, ProductFilters, Stats,
  fetchFacets, fetchProducts, fetchSources, fetchStats, fmtPrice,
  registerSourceNames, sourceName,
} from "../api";
import ProductCard from "../components/ProductCard";
import SourceLogo from "../components/SourceLogo";

const PAGE_SIZE = 60;
const PRICE_STEPS = [1, 2, 3, 5, 8, 10, 15, 20, 30, 50];

const SORT_CHOICES: { key: string; label: string }[] = [
  { key: "price_asc", label: "Prix croissant" },
  { key: "price_desc", label: "Prix décroissant" },
  { key: "unit_price", label: "Prix unitaire" },
  { key: "discount", label: "Meilleur rabais" },
  { key: "name", label: "Nom A→Z" },
  { key: "recent", label: "Nouveautés" },
];

export default function Home({ aubaines = false }: { aubaines?: boolean }) {
  const [products, setProducts] = useState<Product[] | null>(null);
  const [total, setTotal] = useState(0);
  const [offset, setOffset] = useState(0);
  const [loadingMore, setLoadingMore] = useState(false);
  const [facets, setFacets] = useState<Facets | null>(null);
  const [brands, setBrands] = useState<{ brand: string; n: number }[]>([]);
  const [stats, setStats] = useState<Stats | null>(null);
  const [error, setError] = useState<string | null>(null);

  // filtres (pré-remplis depuis l'URL, ex. /?category=… — liens de la page Stats)
  const [params] = useSearchParams();
  const [q, setQ] = useState(params.get("q") ?? "");
  const [category, setCategory] = useState(params.get("category") ?? "");
  const [source, setSource] = useState(params.get("source") ?? "");
  const [brand, setBrand] = useState(params.get("brand") ?? "");
  const [priceMin, setPriceMin] = useState(params.get("price_min") ?? "");
  const [priceMax, setPriceMax] = useState(params.get("price_max") ?? "");
  const [onSale, setOnSale] = useState(aubaines || params.get("on_sale") === "1");
  const [sort, setSort] = useState(params.get("sort") ?? (aubaines ? "discount" : "price_asc"));
  // feuille de filtres mobile (bottom sheet) + panneau avancé desktop
  const [sheetOpen, setSheetOpen] = useState(false);
  const [advOpen, setAdvOpen] = useState(false);
  const saleForced = aubaines;   // la page Aubaines impose « en solde »
  const activeFilters = [q, category, source, brand, priceMin, priceMax,
    !saleForced && onSale ? "1" : ""].filter(Boolean).length;
  const advCount = [brand, source].filter(Boolean).length;

  useEffect(() => {
    // /aubaines : force le filtre solde (et un tri utile par défaut)
    setOnSale(aubaines || params.get("on_sale") === "1");
  }, [aubaines, params]);

  const filters: ProductFilters = useMemo(() => ({
    q, category, source, brand,
    price_min: priceMin, price_max: priceMax,
    on_sale: onSale ? "1" : "",
    sort, limit: String(PAGE_SIZE),
  }), [q, category, source, brand, priceMin, priceMax, onSale, sort]);

  useEffect(() => {
    fetchSources().then((r) => registerSourceNames(r.sources)).catch(() => {});
    fetchFacets().then(setFacets).catch(() => {});
    fetchStats().then(setStats).catch(() => {});
  }, []);

  // marques dépendantes de la catégorie choisie
  useEffect(() => {
    fetchFacets(category || undefined)
      .then((f) => setBrands(f.brands))
      .catch(() => setBrands([]));
  }, [category]);

  useEffect(() => {
    let cancelled = false;
    setProducts(null);
    setOffset(0);
    setError(null);
    fetchProducts(filters)
      .then((r) => {
        if (!cancelled) {
          setProducts(r.products);
          setTotal(r.total);
        }
      })
      .catch((e) => !cancelled && setError(String(e)));
    return () => {
      cancelled = true;
    };
  }, [filters]);

  const loadMore = () => {
    const next = offset + PAGE_SIZE;
    setLoadingMore(true);
    fetchProducts({ ...filters, offset: String(next) })
      .then((r) => {
        setProducts((prev) => [...(prev ?? []), ...r.products]);
        setTotal(r.total);
        setOffset(next);
      })
      .catch((e) => setError(String(e)))
      .finally(() => setLoadingMore(false));
  };

  const resetAll = () => {
    setQ(""); setCategory(""); setSource(""); setBrand("");
    setPriceMin(""); setPriceMax("");
    if (!saleForced) setOnSale(false);
  };

  // pastilles « filtres actifs » — libellé + action de retrait (+ logo bannière)
  const pills: { label: string; clear: () => void; logo?: string }[] = [];
  if (q) pills.push({ label: `« ${q} »`, clear: () => setQ("") });
  if (category) pills.push({ label: category, clear: () => { setCategory(""); setBrand(""); } });
  if (brand) pills.push({ label: brand, clear: () => setBrand("") });
  if (priceMin) pills.push({ label: `≥ ${priceMin} $`, clear: () => setPriceMin("") });
  if (priceMax) pills.push({ label: `≤ ${priceMax} $`, clear: () => setPriceMax("") });
  if (onSale && !saleForced) pills.push({ label: "En solde", clear: () => setOnSale(false) });
  if (source) pills.push({ label: sourceName(source), clear: () => setSource(""), logo: source });

  const shown = products?.length ?? 0;

  return (
    <div className="container">
      <section className="hero">
        <span className={`kicker ${aubaines ? "kicker-sale" : ""}`}>
          {aubaines ? "Aubaines — les meilleurs rabais du moment" : "Agrégateur — épicerie du Québec"}
        </span>
        {aubaines ? (
          <h1>
            Les <span className="hl hl-tomato">aubaines</span> de toutes<br />
            les <span className="outline">circulaires</span>.
          </h1>
        ) : (
          <h1>
            Tous les prix <span className="outline">d'épicerie</span><br />
            du Québec. <span className="hl">Un seul</span> endroit.
          </h1>
        )}
        <p className="lede">
          {aubaines
            ? "Food·Ka repère les produits en solde chez toutes les bannières d'épicerie du Québec et les classe par rabais — comparez avant de remplir le panier."
            : "Food·Ka rassemble les produits affichés par les bannières d'épicerie du Québec — Metro, IGA, Maxi, Super C, Provigo et plus — mis à jour automatiquement, avec prix unitaires et lien direct vers la fiche originale."}
        </p>
        <div className="stat-row">
          <span className="stat-chip"><span className="pulse" /> Données synchronisées en continu</span>
          {stats && (
            <>
              <span className="stat-chip"><b>{stats.total}</b> produits suivis</span>
              <span className="stat-chip"><b>{stats.sources}</b> bannières</span>
              <span className="stat-chip"><b>{stats.on_sale}</b> soldes actifs</span>
              {stats.avg_price != null && (
                <span className="stat-chip">
                  prix moyen <b>{fmtPrice(stats.avg_price)}</b>
                </span>
              )}
            </>
          )}
        </div>
      </section>

      {sheetOpen && (
        <div className="sheet-backdrop" onClick={() => setSheetOpen(false)} aria-hidden="true" />
      )}
      <section className={`filterbar ${sheetOpen ? "open" : ""}`} aria-label="Filtres">
        <div className="sheet-head">
          <span>Filtres</span>
          <button className="sheet-close" onClick={() => setSheetOpen(false)} aria-label="Fermer les filtres">
            ✕
          </button>
        </div>

        {/* — rangée principale : recherche, catégorie, prix, tri, + filtres — */}
        <div className="f-primary">
          <div className="f-search">
            <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" aria-hidden="true">
              <circle cx="11" cy="11" r="7" /><path d="m20 20-3.5-3.5" />
            </svg>
            <input
              id="f-q" placeholder="Produit, marque, rayon…" value={q}
              onChange={(e) => setQ(e.target.value)}
              aria-label="Recherche"
            />
            {q && (
              <button className="f-clear" onClick={() => setQ("")} aria-label="Effacer la recherche">✕</button>
            )}
          </div>
          <label className="f-ctl">
            <span>Catégorie</span>
            <select value={category} onChange={(e) => { setCategory(e.target.value); setBrand(""); }}>
              <option value="">Toutes</option>
              {(facets?.categories ?? []).map((c) => (
                <option key={c.category} value={c.category}>{c.category}</option>
              ))}
            </select>
          </label>
          <div className="f-ctl">
            <span>Prix</span>
            <div className="range-pair">
              <select aria-label="Prix minimum" value={priceMin}
                onChange={(e) => setPriceMin(e.target.value)}>
                <option value="">Min</option>
                {PRICE_STEPS.map((p) => (
                  <option key={p} value={p} disabled={!!priceMax && p >= Number(priceMax)}>
                    {p} $
                  </option>
                ))}
              </select>
              <span className="range-sep">—</span>
              <select aria-label="Prix maximum" value={priceMax}
                onChange={(e) => setPriceMax(e.target.value)}>
                <option value="">Max</option>
                {PRICE_STEPS.map((p) => (
                  <option key={p} value={p} disabled={!!priceMin && p <= Number(priceMin)}>
                    {p} $
                  </option>
                ))}
              </select>
            </div>
          </div>
          <label className="f-ctl">
            <span>Trier par</span>
            <select value={sort} onChange={(e) => setSort(e.target.value)}>
              {SORT_CHOICES.map((s) => (
                <option key={s.key} value={s.key}>{s.label}</option>
              ))}
            </select>
          </label>
          <button
            className={`f-more ${advOpen || advCount > 0 ? "on" : ""}`}
            onClick={() => setAdvOpen(!advOpen)}
            aria-expanded={advOpen}
          >
            Plus de filtres{advCount > 0 ? ` · ${advCount}` : ""} {advOpen ? "▴" : "▾"}
          </button>
        </div>

        {/* — panneau avancé : bannière, marque, solde — */}
        {(advOpen || sheetOpen) && (
          <div className="f-adv">
            <div className="f-group">
              <label>Bannière</label>
              <select className="f-native" value={source} onChange={(e) => setSource(e.target.value)}>
                <option value="">Toutes</option>
                {(facets?.sources ?? []).map((s) => (
                  <option key={s.source} value={s.source}>
                    {sourceName(s.source)} ({s.n})
                  </option>
                ))}
              </select>
            </div>
            <div className="f-group">
              <label>Marque</label>
              <select className="f-native" value={brand} onChange={(e) => setBrand(e.target.value)}>
                <option value="">Toutes</option>
                {brands.map((b) => (
                  <option key={b.brand} value={b.brand}>
                    {b.brand} ({b.n})
                  </option>
                ))}
              </select>
            </div>
            {!saleForced && (
              <div className="f-group">
                <label>Soldes</label>
                <div className="seg" role="group">
                  <button className={!onSale ? "on" : ""} onClick={() => setOnSale(false)}>
                    Tous les produits
                  </button>
                  <button className={onSale ? "on" : ""} onClick={() => setOnSale(true)}>
                    🔥 En solde{facets ? ` (${facets.on_sale})` : ""}
                  </button>
                </div>
              </div>
            )}
            <div className="f-group f-group-end">
              <button className="btn btn-ghost" onClick={resetAll} disabled={activeFilters === 0}>
                Tout réinitialiser{activeFilters > 0 ? ` (${activeFilters})` : ""}
              </button>
            </div>
          </div>
        )}

        <button className="btn btn-primary sheet-apply" onClick={() => setSheetOpen(false)}>
          Voir les résultats {products ? `(${total})` : ""}
        </button>
      </section>

      <div className="chips" role="group" aria-label="Filtres rapides">
        {(facets?.categories ?? []).slice(0, 8).map((c) => (
          <button
            key={c.category}
            className={`chip ${category === c.category ? "on" : ""}`}
            onClick={() => { setCategory(category === c.category ? "" : c.category); setBrand(""); }}
          >
            {c.category}
          </button>
        ))}
        {!saleForced && (
          <>
            <span className="chip-sep" aria-hidden="true" />
            <button
              className={`chip ${onSale ? "on" : ""}`}
              onClick={() => setOnSale(!onSale)}
            >
              🔥 En solde
            </button>
          </>
        )}
      </div>

      {pills.length > 0 && (
        <div className="pills" aria-label="Filtres actifs">
          {pills.map((p) => (
            <button key={p.label} className="pill" onClick={p.clear}
              aria-label={`Retirer le filtre ${p.label}`}>
              {p.logo && <SourceLogo source={p.logo} size={18} fallback="hide" />}
              {p.label} <span className="pill-x">✕</span>
            </button>
          ))}
          <button className="pill pill-clear" onClick={resetAll}>
            Tout effacer
          </button>
        </div>
      )}

      <div className="results-head">
        <h2>{aubaines ? "Aubaines en cours" : "Produits"}</h2>
        {products && <span>{total} résultat{total > 1 ? "s" : ""}</span>}
      </div>

      {error && (
        <div className="notice">
          <div className="big">⚠️</div>
          <h2>Impossible de charger les produits</h2>
          <p>{error}</p>
          <button className="btn btn-primary" onClick={() => window.location.reload()}>
            Réessayer
          </button>
        </div>
      )}

      {!error && products === null && (
        <div className="grid" aria-busy="true">
          {Array.from({ length: 8 }).map((_, i) => (
            <div className="skel" key={i}>
              <div className="sk-img" />
              <div className="sk-line" />
              <div className="sk-line short" />
            </div>
          ))}
        </div>
      )}

      {!error && products !== null && products.length === 0 && (
        <div className="notice">
          <div className="big">🔍</div>
          <h2>Aucun produit ne correspond</h2>
          <p>
            Essayez d'élargir vos critères
            {activeFilters > 0 && (
              <> — ou <button className="link-btn" onClick={resetAll}>retirez les {activeFilters} filtres actifs</button></>
            )}.
          </p>
        </div>
      )}

      {!error && products !== null && products.length > 0 && (
        <>
          <div className="grid">
            {products.map((p) => (
              <ProductCard key={p.uid} p={p} />
            ))}
          </div>
          {shown < total && (
            <div className="load-more">
              <button className="btn btn-primary" onClick={loadMore} disabled={loadingMore}>
                {loadingMore ? "Chargement…" : `Charger plus (${shown} / ${total})`}
              </button>
            </div>
          )}
        </>
      )}

      {/* Bouton flottant mobile — ouvre la feuille de filtres */}
      <button
        className="fab"
        onClick={() => setSheetOpen(true)}
        aria-label="Ouvrir les filtres"
      >
        ⚙ Filtres{activeFilters > 0 ? ` · ${activeFilters}` : ""}
      </button>
    </div>
  );
}
