/* global React, PAPERS, BRANDS, FINISHES, COLOR_GROUPS, CATEGORIES, PaperCard, BrandStamp, Icon */
const { useState, useEffect, useMemo, useCallback, useRef } = React;

function GalleryPage({ navigate, tweaks, cart, addToCart, compare, toggleCompare, openCompareModal, query, catalog, catalogLoading, catalogError }) {
  // ----- Filter state -----
  const [activeCat, setActiveCat] = useState(query.cat || "all");
  const [selBrands, setSelBrands] = useState(query.brand ? [query.brand] : []);
  const [selFinishes, setSelFinishes] = useState([]);
  const [selColors, setSelColors] = useState([]);
  const [gsmMin, setGsmMin] = useState(60);
  const [gsmMax, setGsmMax] = useState(350);
  const [sort, setSort] = useState("featured");
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [mobileAccOpen, setMobileAccOpen] = useState(false);

  const PAGE_SIZE = 12;
  const [page, setPage] = useState(1);

  var activePapers = catalog && catalog.length > 0 ? catalog : (window.PAPERS || []);
  var activeCategories = (catalog && catalog.length > 0 && catalog[0] && catalog[0].acc_id)
    ? (window.ACC_CATEGORIES || window.CATEGORIES)
    : window.CATEGORIES;

  // Reset activeCat kalau value lama tidak ada di activeCategories baru
  useEffect(() => {
    if (activeCat !== "all" && !activeCategories.find(c => c.id === activeCat)) {
      setActiveCat("all");
    }
  }, [activeCategories]);

  // sync external query (e.g. nav links)
  useEffect(() => {
    if (query.cat) setActiveCat(query.cat);
    if (query.brand) setSelBrands([query.brand]);
  }, [query.cat, query.brand]);

  useEffect(() => { setPage(1); }, [activeCat, selBrands, selFinishes, selColors, gsmMin, gsmMax]);

  const toggleSet = (set, setSetter, val) => {
    setSetter(set.includes(val) ? set.filter(x => x !== val) : [...set, val]);
  };

  // ----- Apply filters -----
  const filtered = useMemo(() => {
    const cat = activeCategories.find(c => c.id === activeCat) || activeCategories[0];
    let list = activePapers.filter(p => cat.match(p));
    if (selBrands.length) list = list.filter(p => selBrands.includes(p.brand));
    if (selFinishes.length) list = list.filter(p => selFinishes.includes(p.finish));
    if (selColors.length) list = list.filter(p => selColors.includes(p.colorGroup));
    list = list.filter(p => p.gsm >= gsmMin && p.gsm <= gsmMax);
    list = list.filter(p => (p.price_min || 0) >= 100 || Object.keys(p.price || {}).length > 0);

    if (sort === "price-asc") list = [...list].sort((a,b) => (a.price_min || 0) - (b.price_min || 0));
    else if (sort === "price-desc") list = [...list].sort((a,b) => (b.price_min || 0) - (a.price_min || 0));
    else if (sort === "gsm-asc") list = [...list].sort((a,b) => a.gsm - b.gsm);
    else if (sort === "gsm-desc") list = [...list].sort((a,b) => b.gsm - a.gsm);
    else if (sort === "featured") list = [...list].sort((a,b) => (b.featured?1:0) - (a.featured?1:0));
    return list;
  }, [activePapers, activeCat, selBrands, selFinishes, selColors, gsmMin, gsmMax, sort]);

  const visiblePapers = filtered.slice(0, page * PAGE_SIZE);
  const hasMore = filtered.length > page * PAGE_SIZE;

  // ----- Counts per category -----
  const catCounts = useMemo(() => {
    const o = {};
    activeCategories.forEach(c => { o[c.id] = activePapers.filter(p => c.match(p)).length; });
    return o;
  }, [activePapers, activeCategories]);

  // ----- Active filter chips -----
  const activeChips = [];
  if (activeCat !== "all" && activeCategories.find(c=>c.id===activeCat)) activeChips.push({ label: activeCategories.find(c=>c.id===activeCat).label, clear: () => setActiveCat("all") });
  selBrands.forEach(b => activeChips.push({ label: b, clear: () => setSelBrands(selBrands.filter(x => x !== b)) }));
  selFinishes.forEach(f => activeChips.push({ label: f, clear: () => setSelFinishes(selFinishes.filter(x => x !== f)) }));
  selColors.forEach(c => activeChips.push({ label: COLOR_GROUPS.find(g => g.id === c).label, clear: () => setSelColors(selColors.filter(x => x !== c)) }));
  if (gsmMin !== 60 || gsmMax !== 350) activeChips.push({ label: `${gsmMin}–${gsmMax}gsm`, clear: () => { setGsmMin(60); setGsmMax(350); } });

  const clearAll = () => {
    setActiveCat("all"); setSelBrands([]); setSelFinishes([]); setSelColors([]); setGsmMin(60); setGsmMax(350);
  };

  const filterPos = tweaks.filterPos || "left-rail";
  const gridType = (catalog && catalog[0] && catalog[0].acc_id) ? "uniform" : (tweaks.gridType || "editorial");
  const density = tweaks.density || "default";

  // Hide sidebar on mobile — accordion handles filters there
  const [windowW, setWindowW] = useState(typeof window !== "undefined" ? window.innerWidth : 1200);
  useEffect(() => {
    const onResize = () => setWindowW(window.innerWidth);
    window.addEventListener("resize", onResize);
    return () => window.removeEventListener("resize", onResize);
  }, [activePapers, activeCategories]);
  const isMobile = windowW <= 980;
  const sidebarVisible = filterPos === "left-rail" && !isMobile;

  return (
    <main className={"density-" + density}>
      {/* -------- HERO -------- */}
      <Hero />

      <BrandValuesStrip />
      <FeaturedCollections navigate={navigate} />
      <BrandSpotlight navigate={navigate} />

      {catalogLoading && (
        <div style={{padding:'20px',textAlign:'center',fontFamily:'var(--font-mono)',fontSize:12,color:'var(--ink-meta)',letterSpacing:'0.08em'}}>
          Memuat catalog…
        </div>
      )}
      {catalogError && !catalogLoading && (
        <div style={{padding:'8px var(--gutter)',background:'var(--terracotta-wash)',color:'var(--terracotta-deep)',fontSize:11,fontFamily:'var(--font-mono)',textAlign:'center'}}>
          Menggunakan data lokal.
        </div>
      )}

      {/* -------- Top filter bar (categories) -------- */}
      <div className="filter-bar">
        <div className="filter-bar-inner">
          <span className="label">Browse</span>
          {activeCategories.map(c => (
            <button
              key={c.id}
              className={"filter-chip" + (activeCat === c.id ? " is-active" : "")}
              onClick={() => setActiveCat(c.id)}
            >
              {c.label}
              <span className="count">{catCounts[c.id]}</span>
            </button>
          ))}
          <div className="spacer" />
          {filterPos === "top-bar" && (
            <button className="filter-toggle-side" onClick={() => setDrawerOpen(true)}>
              <Icon.Filter /> More filters
            </button>
          )}
        </div>
      </div>

      {/* -------- Mobile filter accordion -------- */}
      <div className={"mobile-filter-accordion" + (mobileAccOpen ? " is-open" : "")}>
        <button className="mfa-toggle" onClick={() => setMobileAccOpen(o => !o)}>
          <span>Filter</span>
          <span className="mfa-toggle-right">
            {(() => { const n = selBrands.length + selFinishes.length + selColors.length + (gsmMin !== 60 || gsmMax !== 350 ? 1 : 0); return n > 0 ? <span className="mfa-badge">{n}</span> : null; })()}
            <span className="mfa-chevron">+</span>
          </span>
        </button>
        <div className="mfa-inner">
          <div className="mfa-grid">
            <div>
              <div className="mfa-group-title">Brand</div>
              <div className="mfa-pills">
                {BRANDS.map(b => <button key={b} className={"mfa-pill" + (selBrands.includes(b) ? " is-active" : "")} onClick={() => toggleSet(selBrands, setSelBrands, b)}>{b}</button>)}
              </div>
            </div>
            <div>
              <div className="mfa-group-title">Finish</div>
              <div className="mfa-pills">
                {FINISHES.map(f => <button key={f} className={"mfa-pill" + (selFinishes.includes(f) ? " is-active" : "")} onClick={() => toggleSet(selFinishes, setSelFinishes, f)}>{f}</button>)}
              </div>
            </div>
            <div className="mfa-range-wrap">
              <div className="mfa-group-title">Berat Kertas</div>
              <div className="mfa-range-vals"><span>{gsmMin} gsm</span><span>{gsmMax} gsm</span></div>
              <input type="range" min="60" max="350" step="10" value={gsmMin} onChange={e => setGsmMin(Math.min(Number(e.target.value), gsmMax - 10))} style={{width:"100%", marginBottom:6}} />
              <input type="range" min="60" max="350" step="10" value={gsmMax} onChange={e => setGsmMax(Math.max(Number(e.target.value), gsmMin + 10))} style={{width:"100%"}} />
            </div>
            <div>
              <div className="mfa-group-title">Warna</div>
              <div className="mfa-colors">
                {COLOR_GROUPS.map(g => <button key={g.id} className={"mfa-color-btn" + (selColors.includes(g.id) ? " is-active" : "")} style={{background: g.swatch, border: "2px solid " + (selColors.includes(g.id) ? "var(--ink)" : "var(--paper-card-edge)")}} onClick={() => toggleSet(selColors, setSelColors, g.id)} title={g.label} />)}
              </div>
            </div>
          </div>
          {(selBrands.length + selFinishes.length + selColors.length + (gsmMin !== 60 || gsmMax !== 350 ? 1 : 0)) > 0 && (
            <button className="mfa-reset" onClick={clearAll}>Reset filter</button>
          )}
        </div>
      </div>

      {/* -------- Main gallery body -------- */}
      <div className={"shell gallery-body" + (sidebarVisible ? "" : " no-sidebar")}>
        {sidebarVisible && (
          <aside className={"gallery-sidebar" + (drawerOpen ? " is-drawer-open" : "")}>
            <FilterPanel
              selBrands={selBrands} setSelBrands={setSelBrands} toggleSet={toggleSet}
              selFinishes={selFinishes} setSelFinishes={setSelFinishes}
              selColors={selColors} setSelColors={setSelColors}
              gsmMin={gsmMin} setGsmMin={setGsmMin}
              gsmMax={gsmMax} setGsmMax={setGsmMax}
              onClose={() => setDrawerOpen(false)}
              showCloseBtn={drawerOpen}
            />
          </aside>
        )}

        <section className="gallery-main">
          {/* Toolbar */}
          <div className="gallery-toolbar">
            <div className="count">
              <strong>{filtered.length}</strong> kertas
              {activeCat !== "all" && activeCategories.find(c=>c.id===activeCat) && <> · <span style={{color:"var(--ink-soft)"}}>{activeCategories.find(c=>c.id===activeCat)?.label}</span></>}
            </div>
            <div className="sort">
              <span className="eyebrow">Sort</span>
              <select value={sort} onChange={(e)=>setSort(e.target.value)}>
                <option value="featured">Featured</option>
                <option value="price-asc">Price · low to high</option>
                <option value="price-desc">Price · high to low</option>
                <option value="gsm-asc">Weight · light to heavy</option>
                <option value="gsm-desc">Weight · heavy to light</option>
              </select>
            </div>
          </div>

          {/* Active filter chips */}
          {activeChips.length > 0 && (
            <div className="active-filters">
              {activeChips.map((ch, i) => (
                <span key={i} className="active-chip">
                  {ch.label}
                  <button className="x" onClick={ch.clear} style={{background:"none", border:"none", cursor:"pointer", display:"inline-flex", color:"inherit"}}><Icon.X /></button>
                </span>
              ))}
              <button className="clear-all" onClick={clearAll}>Clear all</button>
            </div>
          )}

          {/* Grid */}
          {filtered.length === 0 ? (
            <EmptyState clearAll={clearAll} />
          ) : (
            <div className={"paper-grid grid-" + gridType}>
              {visiblePapers.map(p => (
                <PaperCard
                  key={p.id}
                  paper={p}
                  onOpen={() => navigate("/product/" + p.id)}
                  onAddCart={() => addToCart(p)}
                  onToggleCompare={() => toggleCompare(p)}
                  isComparing={compare.some(x => x.id === p.id)}
                  onRequestSample={(paper) => { addSampleToList(paper); navigate("/sample-request"); }}
                />
              ))}
            </div>
          )}

          {hasMore && (
            <div style={{textAlign:'center', padding:'40px 0 20px'}}>
              <button
                className="btn btn-ghost btn-lg"
                onClick={() => setPage(p => p + 1)}
                style={{minWidth:200}}
              >
                Load more — {filtered.length - page * PAGE_SIZE} kertas lagi
              </button>
            </div>
          )}
        </section>
      </div>

      {/* -------- Featured Fedrigoni banner -------- */}
      <FedrigoniBanner navigate={navigate} />

      {/* -------- Sample kit strip -------- */}
      <SampleKitStrip navigate={navigate} />
    </main>
  );
}

// helper for "request sample" cta from card — stash in localStorage
function addSampleToList(paper) {
  try {
    const cur = JSON.parse(localStorage.getItem("ip_samples") || "[]");
    if (!cur.find(x => x.id === paper.id)) {
      cur.push({ id: paper.id, brand: paper.brand, name: paper.name, gsm: paper.gsm, finish: paper.finish, tone: paper.swatchTone });
      localStorage.setItem("ip_samples", JSON.stringify(cur));
    }
  } catch (e) {}
}

// ============================================================
// HERO
// ============================================================
const HERO_WORDS = ["paper.", "texture.", "kraft.", "bamboo.", "felt.", "letterpress.", "arcoprint.", "swatch.", "premium."];

function TypedWord() {
  const prefersReduced = useRef(
    typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches
  );
  const [display, setDisplay] = useState("paper.");
  const [phase, setPhase] = useState("hold");
  const [idx, setIdx] = useState(0);

  useEffect(() => {
    let timeout;
    const word = HERO_WORDS[idx];

    if (phase === "hold") {
      timeout = setTimeout(() => setPhase("delete"), 1800);
    } else if (phase === "delete") {
      if (display.length > 0) {
        timeout = setTimeout(() => setDisplay(d => d.slice(0, -1)), 55);
      } else {
        const next = (idx + 1) % HERO_WORDS.length;
        setIdx(next);
        setPhase("type");
      }
    } else if (phase === "type") {
      const target = HERO_WORDS[idx];
      if (display.length < target.length) {
        timeout = setTimeout(() => setDisplay(target.slice(0, display.length + 1)), 80);
      } else {
        setPhase("hold");
      }
    }
    return () => clearTimeout(timeout);
  }, [phase, display, idx]);

  if (false && prefersReduced.current) {
    return <em>paper.</em>;
  }
  return (
    <em style={{display:"inline-flex", alignItems:"baseline", whiteSpace:"nowrap"}}>
      {display}
      <span style={{
        display:"inline-block", width:3, height:"0.85em",
        background:"var(--terracotta)", marginLeft:4,
        animation:"typed-blink 600ms steps(1) infinite",
        verticalAlign:"baseline",
      }} />
    </em>
  );
}

function Hero() {
  return (
    <section className="hero" style={{overflow:"hidden", position:"relative"}}>
      {/* Dashed flight path — clipped dalam hero bounds */}
      <svg
        viewBox="0 0 100 60"
        preserveAspectRatio="none"
        aria-hidden="true"
        style={{
          position:"absolute", inset:0, width:"100%", height:"100%",
          pointerEvents:"none", zIndex:1, overflow:"hidden",
        }}
      >
        <path
          d="M2 55 Q 25 38 50 22 T 98 6"
          stroke="var(--paper-card-edge)"
          strokeWidth="0.5"
          strokeDasharray="2 3"
          fill="none"
          vectorEffect="non-scaling-stroke"
        />
      </svg>
      {/* Paper plane — posisi CSS, bukan SVG transform */}
      <div className="hero-plane" aria-hidden="true" style={{
        animationPlayState:'running',
        animation:'plane-fly 16s linear infinite',
        display:'block',
      }}>
        <svg width="22" height="16" viewBox="0 0 22 16" fill="none" style={{display:"block"}}>
          <polygon points="0,8 22,0 14,10" fill="var(--ink)" opacity="0.8"/>
          <polygon points="0,8 14,10 11,14 9,10" fill="var(--brand-yellow)" opacity="0.9"/>
        </svg>
      </div>

      <div className="shell" style={{position:"relative", zIndex:2}}>
        <div className="hero-inner">
          <h1>
            Find<br/>
            <TypedWord /><br/>
          </h1>
          <div className="hero-meta">
            <span className="eyebrow eyebrow-ink">「 The Gallery 」 ペーパー</span>
            <p>Specialty paper untuk designer, studio kreatif, dan brand yang peduli kualitas. Pre-cut A4 / A3 / SRA3 — MOQ 10 lembar.</p>
            <div className="stats">
              <div className="stat"><span className="n serif">302</span><span className="l">papers in stock</span></div>
              <div className="stat"><span className="n serif">8</span><span className="l">categories</span></div>
              <div className="stat"><span className="n serif">10</span><span className="l">min order</span></div>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

// ============================================================
// BRAND VALUES STRIP
// ============================================================
function BrandValuesStrip() {
  return (
    <section className="brand-values">
      <div className="shell brand-values-inner">
        <div className="bv-item">
          <div className="bv-icon">✦</div>
          <div>
            <div className="bv-title">Pre-cut, siap pakai</div>
            <div className="bv-desc">A3+ pre-cut untuk semua kertas. Tidak perlu beli rim — order mulai 10 lembar.</div>
          </div>
        </div>
        <div className="bv-divider" />
        <div className="bv-item">
          <div className="bv-icon">◈</div>
          <div>
            <div className="bv-title">Brand premium dunia</div>
            <div className="bv-desc">Mohawk, Conqueror, Fedrigoni, Antalis — kertas yang sama dipakai studio terbaik di Eropa dan Amerika.</div>
          </div>
        </div>
        <div className="bv-divider" />
        <div className="bv-item">
          <div className="bv-icon">◎</div>
          <div>
            <div className="bv-title">Jakarta, kirim cepat</div>
            <div className="bv-desc">Stok tersedia di Jakarta. Jabodetabek 1–2 hari kerja, luar kota 3–5 hari.</div>
          </div>
        </div>
      </div>
    </section>
  );
}

// ============================================================
// FEATURED COLLECTIONS
// ============================================================
function FeaturedCollections({ navigate }) {
  const collections = [
    {
      id: 'fancy',
      label: 'Fancy Paper',
      desc: 'Kertas premium dengan tekstur dan finishing eksklusif — untuk karya yang benar-benar berkesan.',
      tone: '#F4EFE3',
      grain: 'felt',
      cat: 'fancy',
      count: '133 produk',
    },
    {
      id: 'creative',
      label: 'Creative Paper',
      desc: 'Pilihan kreatif untuk desainer — warna, tekstur, dan permukaan yang tidak biasa.',
      tone: '#E8E0D0',
      grain: 'smooth',
      cat: 'creative',
      count: '51 produk',
    },
    {
      id: 'standard',
      label: 'Standard Paper',
      desc: 'Kertas berkualitas untuk kebutuhan sehari-hari studio — reliable, konsisten, harga terjangkau.',
      tone: '#F0EBE0',
      grain: 'smooth',
      cat: 'standard',
      count: '21 produk',
    },
    {
      id: 'eco',
      label: 'Eco Series',
      desc: 'Kertas ramah lingkungan — FSC certified, bamboo fiber, recycled content.',
      tone: '#E8EDE0',
      grain: 'fiber',
      cat: 'eco',
      count: 'Eco certified',
      eco: true,
    },
  ];

  return (
    <section className="featured-collections">
      <div className="shell">
        <div className="section-head" style={{marginBottom: 32}}>
          <div>
            <span className="eyebrow eyebrow-ink">「 Collections 」</span>
            <h2 style={{marginTop: 8}}>Browse by <em>category</em></h2>
          </div>
        </div>
        <div className="fc-grid">
          {collections.map(col => (
            <div
              key={col.id}
              className="fc-card"
              onClick={() => navigate('/gallery?cat=' + col.cat)}
            >
              <div className="fc-swatch" style={{position:'relative', overflow:'hidden'}}>
                <PaperTexture tone={col.tone} grain={col.grain} />
                {col.eco && (
                  <span className="badge badge-eco" style={{position:'absolute', top:12, left:12}}>Eco · FSC</span>
                )}
              </div>
              <div className="fc-body">
                <div className="fc-label">{col.label}</div>
                <div className="fc-desc">{col.desc}</div>
                <div className="fc-meta">
                  <span className="mono">{col.count}</span>
                  <span className="fc-arrow">→</span>
                </div>
              </div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

// ============================================================
// BRAND SPOTLIGHT — Mohawk
// ============================================================
function BrandSpotlight({ navigate }) {
  return (
    <section className="brand-spotlight">
      <div className="shell brand-spotlight-inner">
        <div className="bs-content">
          <span className="eyebrow" style={{color:'rgba(255,255,255,0.5)'}}>「 Featured Brand 」</span>
          <h2 style={{marginTop:12, color:'#fff'}}>
            The Mohawk<br/><em style={{color:'var(--brand-yellow)'}}>Collection</em>
          </h2>
          <p style={{color:'rgba(255,255,255,0.7)', maxWidth:'48ch', lineHeight:1.7}}>
            Pabrik kertas premium independen terbesar di Amerika Utara. Mohawk Via Felt, Superfine, Loop — kertas yang sama dipakai studio dan desainer terbaik di seluruh dunia, kini tersedia di Jakarta mulai 10 lembar.
          </p>
          <div className="bs-stats">
            <div className="bs-stat"><span className="n">25+</span><span className="l">produk Mohawk</span></div>
            <div className="bs-stat"><span className="n">90–300</span><span className="l">gsm range</span></div>
            <div className="bs-stat"><span className="n">USA</span><span className="l">origin</span></div>
          </div>
          <button
            className="btn btn-lg"
            style={{background:'var(--brand-yellow)', color:'var(--brand-navy)', marginTop:8}}
            onClick={() => navigate('/gallery?brand=Mohawk')}
          >
            Browse Mohawk →
          </button>
        </div>
        <div className="bs-visual">
          <div style={{position:'relative', height:'100%', minHeight:280}}>
            <PaperTexture tone="#F7F2E8" grain="felt" />
            <div style={{
              position:'absolute', bottom:16, left:16,
              fontFamily:'var(--font-mono)', fontSize:11,
              letterSpacing:'0.12em', color:'var(--ink)',
              background:'rgba(255,255,255,0.9)',
              padding:'6px 12px',
            }}>MOHAWK VIA FELT · USA</div>
          </div>
        </div>
      </div>
    </section>
  );
}

// ============================================================
// FILTER PANEL
// ============================================================
function FilterPanel({
  selBrands, setSelBrands, toggleSet,
  selFinishes, setSelFinishes,
  selColors, setSelColors,
  gsmMin, setGsmMin, gsmMax, setGsmMax,
  onClose, showCloseBtn,
}) {
  return (
    <>
      {showCloseBtn && (
        <div style={{display:"flex", justifyContent:"space-between", alignItems:"center", marginBottom: 16}}>
          <strong style={{fontFamily:"var(--font-display)", fontSize: 24}}>Filters</strong>
          <button className="btn btn-ghost btn-sm" onClick={onClose}><Icon.X /> Close</button>
        </div>
      )}

      <div className="group">
        <h4>Brand</h4>
        {BRANDS.map(b => (
          <label className="opt" key={b}>
            <input type="checkbox" checked={selBrands.includes(b)} onChange={() => toggleSet(selBrands, setSelBrands, b)} />
            <span className="box"></span>
            <span>{b}</span>
            <span className="count">{PAPERS.filter(p => p.brand === b).length}</span>
          </label>
        ))}
      </div>

      <div className="group">
        <h4>Weight (gsm)</h4>
        <div className="range">
          <div className="vals">
            <span>{gsmMin}</span>
            <span>{gsmMax}</span>
          </div>
          <input type="range" min="60" max="350" step="10" value={gsmMin}
            onChange={(e) => setGsmMin(Math.min(Number(e.target.value), gsmMax - 10))} />
          <input type="range" min="60" max="350" step="10" value={gsmMax}
            onChange={(e) => setGsmMax(Math.max(Number(e.target.value), gsmMin + 10))} />
          <div className="range-labels"><span>60 gsm</span><span>350 gsm</span></div>
        </div>
      </div>

      <div className="group">
        <h4>Finish</h4>
        {FINISHES.map(f => (
          <label className="opt" key={f}>
            <input type="checkbox" checked={selFinishes.includes(f)} onChange={() => toggleSet(selFinishes, setSelFinishes, f)} />
            <span className="box"></span>
            <span>{f}</span>
            <span className="count">{PAPERS.filter(p => p.finish === f).length}</span>
          </label>
        ))}
      </div>

      <div className="group">
        <h4>Color</h4>
        <div className="color-swatches">
          {COLOR_GROUPS.map(g => (
            <button
              key={g.id}
              title={g.label}
              className={selColors.includes(g.id) ? "active" : ""}
              style={{ background: g.swatch, borderColor: g.swatch === "#1A1A18" ? "var(--ink)" : "var(--paper-card-edge)" }}
              onClick={() => toggleSet(selColors, setSelColors, g.id)}
            />
          ))}
        </div>
      </div>

      <div className="group" style={{marginTop:12}}>
        <h4>Print method</h4>
        <label className="opt"><input type="checkbox" /><span className="box"></span><span>Offset</span><span className="count">9</span></label>
        <label className="opt"><input type="checkbox" /><span className="box"></span><span>Letterpress</span><span className="count">5</span></label>
        <label className="opt"><input type="checkbox" /><span className="box"></span><span>Foil Stamping</span><span className="count">4</span></label>
        <label className="opt"><input type="checkbox" /><span className="box"></span><span>Digital</span><span className="count">10</span></label>
      </div>
    </>
  );
}

// ============================================================
// EMPTY STATE
// ============================================================
function EmptyState({ clearAll }) {
  return (
    <div style={{
      padding: "80px 24px",
      textAlign: "center",
      border: "1px dashed var(--paper-card-edge)",
      background: "var(--paper-cream)",
    }}>
      <div style={{fontFamily:"var(--font-display)", fontSize: 36, marginBottom: 8, letterSpacing:"-0.01em"}}>
        Tidak ada kertas yang cocok.
      </div>
      <p style={{color:"var(--ink-meta)", marginBottom: 24}}>Coba longgarkan filter — atau biarkan kami pilihkan.</p>
      <button className="btn btn-primary" onClick={clearAll}>Reset filters</button>
    </div>
  );
}

// ============================================================
// FEATURED FEDRIGONI BANNER
// ============================================================
function FedrigoniBanner({ navigate }) {
  return (
    <section className="featured">
      <div className="shell featured-inner">
        <div className="visual" style={{position:"relative"}}>
          <PaperTexture tone="#F4ECD8" grain="smooth" />
          <image-slot
            id="featured-fedrigoni"
            placeholder="Fedrigoni collection hero (flat lay)"
            shape="rect"
            style={{ position:"absolute", inset:0 }}
          />
          {/* corner sticker */}
          <div style={{
            position:"absolute", top: 16, left: 16,
            background: "var(--paper-bg)",
            padding: "6px 12px",
            fontFamily: "var(--font-mono)",
            fontSize: 11,
            letterSpacing: "0.1em",
            border: "1px solid var(--ink)",
          }}>SINCE 1888 · ITALIA</div>
        </div>
        <div className="content">
          <span className="eyebrow">Featured Collection</span>
          <h2>The <em>Fedrigoni</em><br/>Collection</h2>
          <p>Lebih dari 130 tahun, Fedrigoni adalah standar emas kertas Italia. Dari Arcoprint sampai Sirio Pearl — sekarang tersedia di Jakarta, dipotong sesuai kebutuhan, mulai 10 lembar.</p>
          <div className="featured-actions">
            <button className="btn btn-lg" style={{background:"var(--brand-yellow)", color:"var(--brand-navy)"}} onClick={() => navigate("/gallery?brand=Fedrigoni")}>Browse Fedrigoni</button>
            <button className="btn btn-outline btn-lg" onClick={() => navigate("/sample-request")}>Request swatchbook</button>
          </div>
          <div className="stats-line">
            <span><strong>6</strong> series in stock</span>
            <span><strong>30+</strong> colorways</span>
            <span><strong>90–350</strong> gsm range</span>
          </div>
        </div>
      </div>
    </section>
  );
}

// ============================================================
// SAMPLE KIT STRIP
// ============================================================
function SampleKitStrip({ navigate }) {
  return (
    <section className="sample-strip">
      <div className="shell sample-strip-inner">
        <div>
          <span className="eyebrow eyebrow-ink">「 Free · Gratis 」</span>
          <h3 style={{marginTop:8}}>Belum yakin kertas yang mana? <em>Pesan sample kit.</em></h3>
          <p>Kami kirim 8 lembar kertas pilihan kami (atau pilihan Anda) — gratis ongkir Jakarta, tinggal ditimang, dipegang, dicoba print sendiri.</p>
        </div>
        <button className="btn btn-accent btn-lg" onClick={() => navigate("/sample-request")}>
          Request a sample kit
          <Icon.Arrow />
        </button>
      </div>
    </section>
  );
}

Object.assign(window, {
  GalleryPage,
  Hero, FilterPanel, FedrigoniBanner, SampleKitStrip,
  BrandValuesStrip, FeaturedCollections, BrandSpotlight,
  addSampleToList,
});
