/* ════════════════════════════════════════════════════════════
   Catalog — venues.html + extras.html shared components
   ════════════════════════════════════════════════════════════ */
const { useState: useCat, useMemo: useCatMemo } = React;

// ───── Index hero ─────
function CatalogHero({ eyebrow, h1Pre, h1Mid, h1Post, lede, stats }) {
  return (
    <section className="cat-hero">
      <div className="grain" />
      <div className="neon-ring" style={{width:520,height:520,background:"#FF2E8A",top:-200,left:-180,opacity:0.30}} />
      <div className="neon-ring" style={{width:480,height:480,background:"#FFD15C",top:-100,right:-160,opacity:0.18}} />
      <div className="container cat-hero-inner">
        <div className="h-eyebrow pink" style={{marginBottom:18}}>{eyebrow}</div>
        <h1 className="cat-h1">
          {h1Pre} <span className="txt-pink">{h1Mid}</span> {h1Post}
        </h1>
        <p className="cat-lede">{lede}</p>
        {stats && (
          <div className="cat-stats">
            {stats.map((s, i) => (
              <div key={i}>
                <span className="num">{s.num}</span>
                <span className="lbl">{s.lbl}</span>
              </div>
            ))}
          </div>
        )}
      </div>
    </section>
  );
}

// ───── Filter bar ─────
function FilterBar({ cats, capacityBuckets, sort, state, onChange, activeCount, totalCount, showCapacity = true }) {
  // Mobile-collapsible. Detect viewport on mount + resize.
  const [mobile, setMobile] = useCat(typeof window !== "undefined" && window.matchMedia("(max-width: 720px)").matches);
  const [open, setOpen] = useCat(false);

  React.useEffect(() => {
    const mq = window.matchMedia("(max-width: 720px)");
    const onChg = e => setMobile(e.matches);
    mq.addEventListener("change", onChg);
    return () => mq.removeEventListener("change", onChg);
  }, []);

  // Build a short summary of the active filter state for the collapsed mobile bar
  const summary = React.useMemo(() => {
    const parts = [];
    const catObj = cats.find(c => c.id === state.cat);
    if (catObj && catObj.id !== "all") parts.push(catObj.label);
    if (showCapacity) {
      const capObj = capacityBuckets?.find(b => b.id === state.cap);
      if (capObj && capObj.id !== "all") parts.push(capObj.label);
    }
    const sortObj = sort.find(s => s.id === state.sort);
    if (sortObj && sortObj.id !== "popular") parts.push(sortObj.label);
    return parts.length ? parts.join(" · ") : "All " + (showCapacity ? "venues" : "extras");
  }, [state, cats, capacityBuckets, sort, showCapacity]);

  const expanded = !mobile || open;

  return (
    <div className={"filter-bar " + (mobile ? "filter-bar-mobile " : "") + (expanded ? "filter-bar-open" : "filter-bar-closed")}>
      {mobile && (
        <button
          className="filter-bar-toggle"
          onClick={() => setOpen(v => !v)}
          aria-expanded={open}>
          <span className="filter-bar-toggle-ic" aria-hidden="true">
            <span/><span/><span/>
          </span>
          <span className="filter-bar-toggle-text">
            <strong>Filters</strong>
            <span>{summary}</span>
          </span>
          <span className="filter-bar-toggle-count">
            <strong>{activeCount}</strong>/{totalCount}
          </span>
          <span className={"filter-bar-toggle-chev " + (open ? "open" : "")} aria-hidden="true">⌄</span>
        </button>
      )}

      <div className="filter-bar-inner">
        <div className="filter-grp">
          <span className="filter-lbl">Category</span>
          <div className="filter-pills">
            {cats.map(c => (
              <button
                key={c.id}
                className={"filter-pill " + (state.cat === c.id ? "active" : "")}
                onClick={() => onChange({ ...state, cat: c.id })}>
                {c.label}
              </button>
            ))}
          </div>
        </div>

        {showCapacity && (
          <div className="filter-grp">
            <span className="filter-lbl">Capacity</span>
            <div className="filter-pills">
              {capacityBuckets.map(c => (
                <button
                  key={c.id}
                  className={"filter-pill " + (state.cap === c.id ? "active" : "")}
                  onClick={() => onChange({ ...state, cap: c.id })}>
                  {c.label}
                </button>
              ))}
            </div>
          </div>
        )}

        <div className="filter-grp filter-grp-sort">
          <span className="filter-lbl">Sort</span>
          <select
            value={state.sort}
            onChange={e => onChange({ ...state, sort: e.target.value })}
            className="filter-select">
            {sort.map(s => <option key={s.id} value={s.id}>{s.label}</option>)}
          </select>
        </div>
      </div>
      {!mobile && (
        <div className="filter-count">
          <strong>{activeCount}</strong> of {totalCount} {showCapacity ? "venues" : "extras"}
        </div>
      )}
    </div>
  );
}

// ───── Product card (used in both venues & extras) ─────
function ProductCard({ item, kind }) {
  const href = `product.html?id=${item.id}`;
  return (
    <a className="prod-card" href={href}>
      <div className="prod-card-img">
        <Img src={item.heroImg} alt={item.name} />
        {kind === "venue" && item.capacity && (
          <span className="prod-card-cap">
            <Icon.Star width={11} height={11}/> Up to {item.capacity}
          </span>
        )}
        {kind === "extra" && item.type && (
          <span className="prod-card-cap">{categoryLabel(item.type)}</span>
        )}
      </div>
      <div className="prod-card-body">
        <h3>{item.name}</h3>
        <p className="prod-card-tag">{item.tagline}</p>
        {kind === "venue" && (
          <div className="prod-card-specs">
            <span><Icon.Check width={12} height={12}/>{item.footprint}</span>
            <span><Icon.Check width={12} height={12}/>Setup {item.setupTime}</span>
          </div>
        )}
        <div className="prod-card-foot">
          <div className="prod-card-price">
            <span className="from">From</span>
            <span className="num">£{item.price}</span>
          </div>
          <span className="prod-card-cta">Details <Icon.Arrow /></span>
        </div>
      </div>
    </a>
  );
}

function categoryLabel(type) {
  const map = {
    sound: "Sound",
    lighting: "Lighting & FX",
    furniture: "Furniture",
    photo: "Photobooth",
    decor: "Decor",
    comfort: "Comfort",
    catering: "Catering",
  };
  return map[type] || type;
}

// ───── VENUE INDEX ─────
function VenueIndex() {
  const C = window.PP_CATALOG;
  const [state, setState] = useCat({ cat: "all", cap: "all", sort: "popular" });

  const filtered = useCatMemo(() => {
    let list = C.venues.slice();
    if (state.cat !== "all") list = list.filter(v => v.cat === state.cat);
    const bucket = C.filters.capacityBuckets.find(b => b.id === state.cap);
    if (bucket && bucket.id !== "all") {
      list = list.filter(v => v.capacity >= bucket.min && v.capacity <= bucket.max);
    }
    switch (state.sort) {
      case "low":      list.sort((a,b) => a.price - b.price); break;
      case "high":     list.sort((a,b) => b.price - a.price); break;
      case "cap-low":  list.sort((a,b) => a.capacity - b.capacity); break;
      case "cap-high": list.sort((a,b) => b.capacity - a.capacity); break;
      default: break; // popular = default order
    }
    return list;
  }, [state]);

  return (
    <>
      <CatalogHero
        eyebrow="VENUES · 13 INFLATABLES"
        h1Pre="Every venue we hire,"
        h1Mid="in one place."
        h1Post=""
        lede="From a 4m bubble tent for 10 guests to a 15m flagship dome for 230. Real specs, real footprints, honest prices. Filter by what fits your space."
        stats={[
          { num: "13", lbl: "venues" },
          { num: "10–230", lbl: "capacity range" },
          { num: "£395+", lbl: "from / 24h hire" },
        ]}
      />

      <section className="section cat-section">
        <div className="container">
          <FilterBar
            cats={C.filters.venueCategories}
            capacityBuckets={C.filters.capacityBuckets}
            sort={C.filters.sort}
            state={state}
            onChange={setState}
            activeCount={filtered.length}
            totalCount={C.venues.length}
          />

          {filtered.length === 0 ? (
            <div className="cat-empty">
              <h3>No venues match this combination.</h3>
              <p>Try widening your filters — or talk to us, we'll find what fits.</p>
              <button className="btn btn-ghost" onClick={() => setState({ cat: "all", cap: "all", sort: "popular" })}>
                Clear filters
              </button>
            </div>
          ) : (
            <>
              <div className="prod-grid">
                {filtered.map(v => <ProductCard key={v.id} item={v} kind="venue" />)}
              </div>
              <div className="cat-coming-soon">
                <span className="ic" aria-hidden="true">+</span>
                <div className="body">
                  <h4>More venues coming soon.</h4>
                  <p>We're adding new inflatable formats this season. Want first dibs when a new venue lists?</p>
                </div>
                <a href="mailto:hello@popupparties.uk?subject=Notify%20me%20about%20new%20venues" className="btn btn-ghost btn-sm">Notify me</a>
              </div>
            </>
          )}
        </div>
      </section>
    </>
  );
}

// ───── EXTRAS INDEX ─────
function ExtraIndex() {
  const C = window.PP_CATALOG;
  const [state, setState] = useCat({ cat: "all", cap: "all", sort: "popular" });

  const filtered = useCatMemo(() => {
    let list = C.extras.slice();
    if (state.cat !== "all") list = list.filter(e => e.type === state.cat);
    switch (state.sort) {
      case "low":  list.sort((a,b) => a.price - b.price); break;
      case "high": list.sort((a,b) => b.price - a.price); break;
      default: break;
    }
    return list;
  }, [state]);

  return (
    <>
      <CatalogHero
        eyebrow="EXTRAS · 25 PRODUCTS"
        h1Pre="LED bars, lasers, lights —"
        h1Mid="à la carte."
        h1Post=""
        lede="Bundle these into any venue, or hire them on their own for a venue you've already got. Modular, plug-and-play, delivered with everything you need."
        stats={[
          { num: "25", lbl: "individual items" },
          { num: "£17.50+", lbl: "from" },
          { num: "24hr", lbl: "standard hire" },
        ]}
      />

      <section className="section cat-section">
        <div className="container">
          <FilterBar
            cats={C.filters.extraTypes}
            capacityBuckets={null}
            sort={C.filters.sort.filter(s => !s.id.startsWith("cap-"))}
            state={state}
            onChange={setState}
            activeCount={filtered.length}
            totalCount={C.extras.length}
            showCapacity={false}
          />

          {filtered.length === 0 ? (
            <div className="cat-empty">
              <h3>Nothing in this category.</h3>
              <button className="btn btn-ghost" onClick={() => setState({ cat: "all", cap: "all", sort: "popular" })}>
                Clear filters
              </button>
            </div>
          ) : (
            <>
              <div className="prod-grid">
                {filtered.map(e => <ProductCard key={e.id} item={e} kind="extra" />)}
              </div>
              <div className="cat-coming-soon">
                <span className="ic" aria-hidden="true">+</span>
                <div className="body">
                  <h4>More extras coming soon.</h4>
                  <p>New products land throughout the year — LED tech, photo formats, comfort kit. Get notified when they list.</p>
                </div>
                <a href="mailto:hello@popupparties.uk?subject=Notify%20me%20about%20new%20extras" className="btn btn-ghost btn-sm">Notify me</a>
              </div>
            </>
          )}
        </div>
      </section>
    </>
  );
}

Object.assign(window, { VenueIndex, ExtraIndex, ProductCard, CatalogHero, FilterBar });
