/* IMACX — editorial Categories page + redesigned Catalog (products) page.
   Loaded AFTER pages.jsx / home.jsx so these definitions win.
   Imagery module is a SQUARE (1:1) — supplier product photos are always square. */

/* family meta comes from the supplier-backed category import in data.js */
const FAM_META = Object.fromEntries(
  FAMILIES.map((f) => [f.id, { img: f.image || (PRODUCTS.find((p) => p.fam === f.id)?.img || ""), sub: f.sub || f.name }])
);

/* tiny square — real image if given, else labelled placeholder (ready for supplier photos) */
function Square({ src, label, style }) {
  if (src) return <img src={src} alt={label || ""} loading="lazy" style={style} />;
  return <Placeholder ratio="1/1" label={label} style={style} />;
}

function famProducts(famId) { return PRODUCTS.filter(p => p.fam === famId); }

function normalizeSearchText(value) {
  return String(value || "")
    .normalize("NFD")
    .replace(/[\u0300-\u036f]/g, "")
    .toLowerCase()
    .trim();
}

function productSearchText(product) {
  const family = FAMILIES.find((f) => f.id === product.fam);
  const techNames = (product.printOptions || [])
    .map((tech) => [tech.name, tech.supplierName, tech.sub].filter(Boolean).join(" "))
    .join(" ");
  return normalizeSearchText([
    product.id,
    product.supplierRef,
    product.name,
    product.badge,
    product.blurb,
    product.material,
    product.fam,
    family?.name,
    family?.sub,
    product.details?.material,
    product.details?.origin,
    product.details?.brand,
    (product.colors || []).join(" "),
    (product.techs || []).join(" "),
    techNames
  ].filter(Boolean).join(" "));
}

function productNameSearchText(product) {
  return normalizeSearchText([
    product.id,
    product.supplierRef,
    product.name
  ].filter(Boolean).join(" "));
}

/* =========================================================
   CATEGORIES PAGE
   ========================================================= */
function CategoriesPage({ go, goCatalog, openProduct }) {
  const fams = FAMILIES;
  const total = fams.reduce((s, f) => s + f.n, 0);
  const featured = FAMILIES.find(f => f.id === "mochilas") || FAMILIES[0];

  return (
    <div className="cats" data-screen-label="Categorias">
      <div className="hm-bleed">
        <div className="hm-idx hm-rule-l">
          <span><span className="sq" />Catálogo · {fams.length} categorias</span>
          <span>Lisboa · Porto</span>
          <span className="o">Est. 2026</span>
        </div>

        {/* HERO */}
        <section className="cats-hero">
          <div className="lhs">
            <h1>Escolha por<br /><span className="o">categoria</span>.</h1>
            <p className="lead">Categorias em português, ligadas a referências reais, materiais, técnicas de marcação e escalões de preço próprios — encontre o ponto de partida da sua campanha.</p>
            <div className="stat">
              <div className="s"><b className="num">{total}</b><span>Referências</span></div>
              <div className="s"><b className="num">6</b><span>Técnicas de marcação</span></div>
              <div className="s"><b className="num">10→10K</b><span>Por encomenda</span></div>
            </div>
          </div>
          <a className="cats-fig" onClick={() => goCatalog(featured.id)} style={{ cursor: "pointer" }}>
            <Square src={FAM_META[featured.id].img} label={featured.name} />
            <div className="cats-figcap">
              <div><span className="e">Mais procurada</span><div className="t">{featured.name}</div></div>
              <span className="num" style={{ fontSize: "var(--t-body-s)" }}>{featured.n} ref.</span>
            </div>
          </a>
        </section>
      </div>

      {/* DIRECTORY */}
      <div className="hm-bleed">
        <div className="hm-idx hm-rule">
          <span><span className="sq" />Todas as categorias</span>
          <span className="o" style={{ cursor: "pointer" }} onClick={() => goCatalog(null)}>Ver todos os produtos →</span>
        </div>
        <section className="cats-dir">
          {fams.map((f, i) => {
            const meta = FAM_META[f.id] || {};
            const prods = famProducts(f.id);
            const peeks = [0, 1, 2].map(k => prods[k]);
            return (
              <a className="catrow" key={f.id} onClick={() => goCatalog(f.id)}>
                <span className="cr-n num">{String(i + 1).padStart(2, "0")}</span>
                <div className="cr-main">
                  <div className="cr-name">{f.name}<span className="arr">{Icons.arrow}</span></div>
                  <div className="cr-sub">{meta.sub}</div>
                </div>
                <div className="cr-peek">
                  {peeks.map((p, k) => (
                    <span className="cr-sq" key={k}>
                      <Square src={p ? p.img : meta.img} label={p ? p.name.split(" ")[0] : f.name} />
                    </span>
                  ))}
                </div>
                <div className="cr-count num">{f.n}<small>referências</small></div>
              </a>
            );
          })}
        </section>

        {/* TECHNIQUES mini-index */}
        <section className="cats-tech">
          <div className="hm-idx hm-rule" style={{ borderBottom: 0 }}>
            <span><span className="sq" />Técnicas de marcação</span>
            <span className="num" style={{ opacity: .6 }}>Produto e personalização sempre separados</span>
          </div>
          <div className="grid">
            {TECHS.filter(t => t.id !== "nenhuma").map((t, i) => (
              <div className="tc" key={t.id}>
                <span className="tn num">{String(i + 1).padStart(2, "0")}</span>
                <span className="th">{t.name}</span>
                <span className="td">Setup {eur(t.setup)} · {eur(t.unit)}/un</span>
              </div>
            ))}
          </div>
        </section>
      </div>

      {/* CLOSING CTA band */}
      <section className="hm-band">
        <div className="hm-bleed in">
          <div>
            <span className="e">— Não sabe por onde começar?</span>
            <h2>Diga-nos a campanha.<br />Sugerimos a <span className="o">categoria</span> certa.</h2>
          </div>
          <div className="r">
            <p>Público, ocasião, prazo e orçamento. A equipa IMACX propõe produtos e técnicas de marcação ajustados — com amostras sempre que fizer sentido validar.</p>
            <div className="hm-cta">
              <button className="btn-accent btn-lg" onClick={() => go("request")}>Pedir orçamento {Icons.arrow}</button>
              <button className="btn btn-lg" style={{ borderColor: "rgba(255,255,255,.35)", color: "#fff", background: "transparent" }} onClick={() => goCatalog(null)}>Explorar catálogo</button>
            </div>
          </div>
        </div>
      </section>
    </div>
  );
}

/* =========================================================
   CATALOG (products) PAGE — editorial, full-bleed
   ========================================================= */
function CatalogPage({ go, goCatalog, openProduct, cols, initialFam, searchQuery = "", onClearSearch }) {
  const [fam, setFam] = useState(initialFam || null);
  const [selected, setSelected] = useState({});   // checkbox/chip/swatch facets EXCLUDING family
  const [price, setPrice] = useState([PRICE_BOUNDS[0], PRICE_BOUNDS[1]]); // [min, max] €/un
  const [sort, setSort] = useState("rel");
  const [drawer, setDrawer] = useState(false);
  const priceActive = price[0] > PRICE_BOUNDS[0] || price[1] < PRICE_BOUNDS[1];
  const normalizedQuery = normalizeSearchText(searchQuery);
  const queryTerms = normalizedQuery ? normalizedQuery.split(/\s+/).filter(Boolean) : [];
  const hasSearch = queryTerms.length > 0;

  useEffect(() => { setFam(initialFam || null); }, [initialFam]);

  const groups = useMemo(() => FACET_GROUPS.filter(g => g.id !== "fam" && g.id !== "tech"), []);
  const toggle = (g, id) => setSelected(s => {
    const cur = s[g] || [];
    return { ...s, [g]: cur.includes(id) ? cur.filter(x => x !== id) : [...cur, id] };
  });
  const clear = (g) => setSelected(s => ({ ...s, [g]: [] }));
  const clearAll = () => { setSelected({}); setPrice([PRICE_BOUNDS[0], PRICE_BOUNDS[1]]); if (onClearSearch) onClearSearch(); };

  const filtered = useMemo(() => {
    const productMatchesFacets = (p) => {
      if (fam && p.fam !== fam) return false;
      if (selected.tech?.length && !selected.tech.some(t => p.techs.includes(t))) return false;
      if (selected.color?.length && !selected.color.some(c => p.colors.includes(c))) return false;
      if (selected.material?.length && !selected.material.includes(p.material)) return false;
      if (selected.eco?.length && !p.eco) return false;
      if (p.base < price[0] || p.base > price[1]) return false;
      if (selected.minq?.length) {
        const ok = selected.minq.some(m => (m === "lt50" && p.minq < 50) || (m === "lt100" && p.minq < 100) || (m === "lt250" && p.minq < 250));
        if (!ok) return false;
      }
      return true;
    };
    const facetMatches = PRODUCTS.filter(productMatchesFacets);
    let r = facetMatches;
    if (hasSearch) {
      const exactNameMatches = facetMatches.filter(p => productNameSearchText(p).includes(normalizedQuery));
      const exactTextMatches = exactNameMatches.length ? [] : facetMatches.filter(p => productSearchText(p).includes(normalizedQuery));
      r = exactNameMatches.length
        ? exactNameMatches
        : exactTextMatches.length
          ? exactTextMatches
          : facetMatches.filter(p => queryTerms.every(term => productSearchText(p).includes(term)));
    }
    if (sort === "price") r = [...r].sort((a, b) => a.base - b.base);
    if (sort === "rating") r = [...r].sort((a, b) => b.rating - a.rating);
    return r;
  }, [fam, selected, sort, price, normalizedQuery]);

  const facetCount = Object.values(selected).reduce((n, ids) => n + (ids ? ids.length : 0), 0) + (priceActive ? 1 : 0) + (hasSearch ? 1 : 0);
  const activeChips = [];
  Object.entries(selected).forEach(([g, ids]) => (ids || []).forEach(id => {
    const grp = groups.find(x => x.id === g);
    const opt = grp?.options.find(o => o.id === id);
    if (opt) activeChips.push({ g, id, label: opt.label || opt.name });
  }));
  if (priceActive) activeChips.push({ price: true, label: `${eur(price[0])} – ${price[1] >= PRICE_BOUNDS[1] ? eur(PRICE_BOUNDS[1]) + "+" : eur(price[1])}` });
  if (hasSearch) activeChips.unshift({ search: true, label: `Pesquisa: ${searchQuery}` });

  const famObj = fam ? FAMILIES.find(f => f.id === fam) : null;
  const showHero = !fam && facetCount === 0 && sort === "rel";
  const season = typeof window.getCurrentSeasonalCampaign === "function"
    ? window.getCurrentSeasonalCampaign()
    : { label: "Verão", familyId: "verao-e-praia" };
  const seasonalProducts = PRODUCTS.filter((product) => product.fam === season.familyId);
  const feat = seasonalProducts.find((product) => product.badge === "Best-seller") || seasonalProducts[0] || PRODUCTS[0];
  const featMeta = FAM_META[feat.fam] || {};

  return (
    <div className="hm-bleed cat2">
      <div className="crumbs">
        <a onClick={() => go("home")} style={{ cursor: "pointer" }}>Início</a><span className="sep">/</span>
        <a onClick={() => go("categories")} style={{ cursor: "pointer" }}>Categorias</a>
        {famObj ? <><span className="sep">/</span><span>{famObj.name}</span></> : <><span className="sep">/</span><span>Todos</span></>}
      </div>

      <div className="cat2-head">
        <div className="lhs">
          <span className="eyebrow">{famObj ? "Categoria" : "Catálogo completo"}</span>
          <h2>{famObj ? famObj.name : "Todos os produtos"}</h2>
          <p className="lead">{famObj ? (FAM_META[fam]?.sub) : "Brindes corporativos prontos a personalizar — filtre por quantidade, cor, preço, material ou sustentabilidade."}</p>
        </div>
        <span className="num-tag">{filtered.length} {filtered.length === 1 ? "produto" : "produtos"}</span>
      </div>

      {/* family quick-filter */}
      <div className="cat2-fambar">
        <button className="fchip" data-on={!fam} onClick={() => setFam(null)}>Tudo <span className="c num">{PRODUCTS.length}</span></button>
        {FAMILIES.map(f => (
          <button className="fchip" key={f.id} data-on={fam === f.id} onClick={() => setFam(f.id)}>
            {f.name} <span className="c num">{f.n}</span>
          </button>
        ))}
      </div>

      {/* toolbar */}
      <div className="cat2-bar">
        <button className="filt-btn" onClick={() => setDrawer(true)}>
          {Icons.rows} Filtros{facetCount ? <span className="c num">{facetCount}</span> : null}
        </button>
        {activeChips.length ? (
          <div className="active-facets">
            {activeChips.map((c, i) => (
              <span className="pill" key={i} onClick={() => c.search ? onClearSearch?.() : c.price ? setPrice([PRICE_BOUNDS[0], PRICE_BOUNDS[1]]) : toggle(c.g, c.id)}>{c.label} {Icons.x}</span>
            ))}
            <a className="muted" style={{ cursor: "pointer", fontSize: "var(--t-body-s)" }} onClick={clearAll}>Limpar</a>
          </div>
        ) : <span className="muted" style={{ fontSize: "var(--t-body-s)" }}>Filtre por quantidade, cor, preço…</span>}
        <select className="selectx" style={{ marginLeft: "auto" }} value={sort} onChange={(e) => setSort(e.target.value)}>
          <option value="rel">Relevância</option>
          <option value="price">Preço (menor)</option>
          <option value="rating">Avaliação</option>
        </select>
      </div>

      {/* featured editorial highlight */}
      {showHero ? (
        <section className="cat2-hero">
          <a className="fig" onClick={() => openProduct(feat)} style={{ cursor: "pointer" }}>
            <Square src={feat.img || featMeta.img} label={feat.name} />
            <div className="tag"><Badge tone="solid">Best-seller</Badge></div>
          </a>
          <div className="info">
            <span className="e">Destaque de {season.label} · <i>{FAMILIES.find(f => f.id === feat.fam)?.name}</i></span>
            <h3>{feat.name}</h3>
            <p>{feat.blurb}</p>
            <div className="ftr">
              <Price tiers={feat.tiers} qty={feat.minq} />
              <span className="muted" style={{ fontSize: "var(--t-body-s)" }}>Mín. {feat.minq} un · {feat.material}</span>
              <button className="btn-accent" onClick={() => openProduct(feat)}>Configurar {Icons.arrow}</button>
            </div>
          </div>
        </section>
      ) : null}

      {/* product grid */}
      {filtered.length ? (
        <div className="pgrid" data-cols={cols} style={{ marginTop: showHero ? 0 : 4 }}>
          {filtered.map(p => <ProductCard key={p.id} p={p} onOpen={openProduct} />)}
        </div>
      ) : (
        <div className="empty"><div className="big">Nenhum produto encontrado</div><p>{hasSearch ? "Experimente outro termo de pesquisa ou limpe os filtros ativos." : "Ajuste os filtros para ver mais resultados."}</p><button className="btn" style={{ marginTop: 16 }} onClick={() => { clearAll(); setFam(null); }}>Limpar filtros</button></div>
      )}

      {/* facet drawer */}
      <div className="drawer-scrim" data-open={drawer} onClick={() => setDrawer(false)} />
      <aside className="fdrawer" data-open={drawer} aria-hidden={!drawer}>
        <div className="fdrawer-hd">
          <h3>Filtros {facetCount ? <span className="muted num">· {facetCount}</span> : null}</h3>
          <button className="iconbtn" onClick={() => setDrawer(false)} aria-label="Fechar">{Icons.x}</button>
        </div>
        <div className="fdrawer-body">
          <FacetSidebar groups={groups} selected={selected} onToggle={toggle} onClear={clear} priceValue={price} onPriceChange={setPrice} />
        </div>
        <div className="fdrawer-foot">
          <button className="btn btn-block" onClick={clearAll}>Limpar</button>
          <button className="btn-accent btn-block" onClick={() => setDrawer(false)}>Ver {filtered.length} produtos</button>
        </div>
      </aside>
    </div>
  );
}

Object.assign(window, { CategoriesPage, CatalogPage, FAM_META });
