// Pull-City — main app: header, cart, quickview, tweaks panel, intersection reveals

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "palette": "violet",
  "holoSheen": true
}/*EDITMODE-END*/;

const TIKTOK_URL = "https://www.tiktok.com/@pullcitytcg?_r=1&_t=ZN-96r22qJM4EY";
const TWITCH_URL = "https://www.twitch.tv/pullcitytcg"; // TODO: confermare handle Twitch
const WHATSAPP_URL = "https://chat.whatsapp.com/";

const HEADER_NAV = [
  { href: "#ygo", label: "Yu-Gi-Oh!" },
  { href: "#pkm", label: "Pokémon" },
  { href: "#op", label: "One Piece" },
  { href: "#dbfw", label: "Dragon Ball" },
  { href: "#ua", label: "Union Arena" },
  { href: "#ccg", label: "CCG" },
  { href: "#mag", label: "Magazine" },
  { href: "https://chat.whatsapp.com/", label: "Vault", ext: true },
];

function Header({ onCart, onSearch, cartCount, scrolled }) {
  const [menuOpen, setMenuOpen] = React.useState(false);
  React.useEffect(() => {
    document.body.style.overflow = menuOpen ? "hidden" : "";
    return () => { document.body.style.overflow = ""; };
  }, [menuOpen]);
  return (
    <React.Fragment>
      <header className={"hdr" + (scrolled ? " scrolled" : "") + (menuOpen ? " menu-open" : "")}>
        <div className="wrap row">
          <a className="brand" href="#" onClick={() => setMenuOpen(false)}>
            <img src="media/logo-header.png" alt="Pull-City TCG" className="brand-img" />
            <span className="brand-name">Pull-City <span className="brand-tcg">TCG</span></span>
          </a>
          <nav className="nav">
            {HEADER_NAV.map((it) => (
              <a key={it.href} href={it.href} {...(it.ext ? { target: "_blank", rel: "noopener" } : {})}>{it.label}</a>
            ))}
          </nav>
          <div className="hdr-actions">
            <div className="hdr-actions-group">
              <button className="icon-btn" onClick={onSearch} title="Cerca prodotti" aria-label="Cerca">
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none"><circle cx="11" cy="11" r="7" stroke="currentColor" strokeWidth="1.6" /><path d="M20 20l-3.5-3.5" stroke="currentColor" strokeWidth="1.6" /></svg>
              </button>
              <button id="cart-btn" className="icon-btn" onClick={onCart} title="Carrello">
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M4 7h16l-1.5 11a2 2 0 01-2 1.7H7.5a2 2 0 01-2-1.7L4 7zM9 7V5a3 3 0 116 0v2" stroke="currentColor" strokeWidth="1.4" /></svg>
                {cartCount > 0 && <span className="badge">{cartCount}</span>}
              </button>
            </div>
            <a className="wa-btn" href="https://chat.whatsapp.com/" target="_blank" rel="noopener" title="Gruppo WhatsApp Pull-City">
              <svg className="wa-ico" width="20" height="20" viewBox="0 0 32 32" aria-hidden="true">
                <path fill="#25D366" d="M16 .5C7.4.5.5 7.4.5 16c0 2.83.74 5.58 2.14 8.01L.5 31.5l7.66-2.01A15.46 15.46 0 0 0 16 31.5C24.6 31.5 31.5 24.6 31.5 16S24.6.5 16 .5z"/>
                <path fill="#fff" d="M23.51 19.86c-.33-.16-1.94-.96-2.24-1.07-.3-.11-.52-.17-.74.17-.22.33-.85 1.07-1.04 1.29-.19.22-.38.25-.71.08-.33-.17-1.39-.51-2.65-1.63-.98-.87-1.64-1.95-1.83-2.28-.19-.33-.02-.51.14-.67.15-.15.33-.38.49-.57.16-.19.22-.33.33-.55.11-.22.06-.41-.03-.57-.08-.16-.74-1.78-1.01-2.44-.27-.65-.54-.56-.74-.57-.19-.01-.41-.01-.63-.01-.22 0-.57.08-.87.41-.3.33-1.14 1.11-1.14 2.71 0 1.6 1.17 3.14 1.33 3.36.16.22 2.3 3.52 5.58 4.93 2.78 1.19 3.34.95 3.95.9.6-.06 1.94-.79 2.21-1.55.27-.76.27-1.41.19-1.55-.08-.14-.3-.22-.63-.38z"/>
              </svg>
            </a>
            <a className="tt-btn" href={TIKTOK_URL} target="_blank" rel="noopener" title="TikTok Pull-City">
              <svg className="tt-ico" width="19" height="19" viewBox="0 0 24 24" aria-hidden="true">
                <path fill="#fff" d="M16.6 5.82a4.28 4.28 0 0 1-1.06-2.82h-3.2v12.06a2.6 2.6 0 1 1-2.04-2.54V9.27a5.8 5.8 0 1 0 5.24 5.77V9.18a7.36 7.36 0 0 0 4.32 1.38V7.36a4.28 4.28 0 0 1-3.26-1.54z"/>
              </svg>
            </a>
            <button className="burger" aria-label="Menu categorie" aria-expanded={menuOpen} onClick={() => setMenuOpen((v) => !v)}>
              <span /><span /><span />
            </button>
          </div>
        </div>
      </header>
      <div className={"mobile-menu" + (menuOpen ? " open" : "")} onClick={() => setMenuOpen(false)}>
        <nav onClick={(e) => e.stopPropagation()}>
          {HEADER_NAV.map((it) => (
            <a key={it.href} href={it.href} {...(it.ext ? { target: "_blank", rel: "noopener" } : {})} onClick={() => setMenuOpen(false)}>{it.label}</a>
          ))}
        </nav>
      </div>
    </React.Fragment>
  );
}

function pcPriceNum(v) {
  if (typeof v === "number") return Number.isFinite(v) ? v : null;
  let s = String(v == null ? "" : v).replace(/[^0-9.,]/g, "");
  if (!s) return null;
  s = s.replace(/\.(?=\d{3}(\D|$))/g, "").replace(",", ".");
  const n = parseFloat(s);
  return Number.isFinite(n) ? n : null;
}
function pcEur(n) { return "€ " + Number(n).toLocaleString("it-IT"); }

function Cart({ open, items, onClose, onQty, onRm, onCheckout }) {
  const nums = items.map((it) => pcPriceNum(it.price));
  const allNum = items.length > 0 && nums.every((n) => n != null);
  const total = allNum ? nums.reduce((s, n, i) => s + n * items[i].qty, 0) : null;
  return (
    <>
      <div className={"cart-overlay" + (open ? " open" : "")} onClick={onClose} />
      <aside className={"cart" + (open ? " open" : "")} aria-hidden={!open}>
        <div className="cart-hd">
          <div className="titles">
            <h3>Il tuo Vault</h3>
            <span className="eyebrow" style={{ display: "block" }}>{items.length} {items.length === 1 ? "pezzo" : "pezzi"}</span>
          </div>
          <button className="x" onClick={onClose} aria-label="Chiudi">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none"><path d="M6 6l12 12M18 6L6 18" stroke="currentColor" strokeWidth="1.6"/></svg>
          </button>
        </div>
        <div className="cart-body">
          {items.length === 0 && (
            <div className="cart-empty">
              <div className="glyph">∅</div>
              <div className="ln">Nessuna carta nel vault.<br />Inizia dai drop di questa settimana.</div>
              <div className="hint">— Premi una pill <span style={{ color: "var(--accent)" }}>Aggiungi</span> per iniziare —</div>
            </div>
          )}
          {items.map((it, idx) => (
            <div key={it.id + "-" + idx} className="citem">
              <div className="thumb">
                {it.image ? (
                  <img src={it.image} alt={it.name}
                       style={{ width: "100%", aspectRatio: "3 / 4.2", objectFit: "cover", borderRadius: 6, display: "block" }}
                       onError={(e) => { e.currentTarget.style.display = "none"; }} />
                ) : (
                  <div style={{ width: "100%", aspectRatio: "3 / 4.2", borderRadius: 6, background: "var(--surface-2)", display: "flex", alignItems: "center", justifyContent: "center", color: "var(--accent)", fontSize: 20 }}>✦</div>
                )}
              </div>
              <div>
                <div className="nm">{it.name}</div>
                <div className="sub">{it.sub}</div>
                {it.status === "preorder" && it.release && (
                  <div className="sub" style={{ color: "var(--accent)", marginTop: 2 }}>Pre-order · {it.release}</div>
                )}
                <div className="qty">
                  <button onClick={() => onQty(idx, -1)}>−</button>
                  <span>{it.qty}</span>
                  <button onClick={() => onQty(idx, +1)}>+</button>
                </div>
              </div>
              <div style={{ textAlign: "right" }}>
                <div className="pr">{(() => { const p = pcPriceNum(it.price); return p == null ? "da concordare" : pcEur(p * it.qty); })()}</div>
                <button className="rm" onClick={() => onRm(idx)}>Rimuovi</button>
              </div>
            </div>
          ))}
        </div>
        {items.length > 0 && (
          <div className="cart-ft">
            <div className="totals">
              <span className="l">Subtotale</span>
              <span className="v">{total == null ? "da concordare" : pcEur(total)}</span>
            </div>
            <div className="note"><span className="dot"></span>Spedizione scelta al checkout · imballo corazzato</div>
            <button className="btn btn-gold" style={{ justifyContent: "center" }} onClick={onCheckout}>
              Procedi al Checkout
              <svg className="arr" width="14" height="14" viewBox="0 0 24 24" fill="none"><path d="M5 12h14M13 6l6 6-6 6" stroke="currentColor" strokeWidth="1.6"/></svg>
            </button>
          </div>
        )}
      </aside>
    </>
  );
}

function QuickView({ product, onClose, onAdd }) {
  const [shared, setShared] = React.useState(false);
  const [rOpen, setROpen] = React.useState(false);
  const [rEmail, setREmail] = React.useState("");
  const [rState, setRState] = React.useState("");
  if (!product) return null;
  const isPre = product.status === "preorder";
  const soldOut = !!product.sold_out || product.stock === 0;
  async function submitRestock(e) {
    e.preventDefault(); setRState("busy");
    const r = await fetch("/api/notify-restock", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ product_id: product.id, email: rEmail }) }).then((x) => x.json()).catch(() => ({ ok: false }));
    setRState(r.ok ? "ok" : "err");
  }
  function share() {
    const url = location.origin + "/p/" + encodeURIComponent(product.id);
    if (navigator.share) { navigator.share({ title: "Pull-City · " + product.name, url }).catch(() => {}); return; }
    if (navigator.clipboard) { navigator.clipboard.writeText(url).then(() => { setShared(true); setTimeout(() => setShared(false), 1800); }); }
    else { window.prompt("Copia il link del prodotto:", url); }
  }
  return (
    <div className={"qv-overlay open"} onClick={onClose}>
      <div className="qv" onClick={(e) => e.stopPropagation()}>
        <button className="qv-close" onClick={onClose} aria-label="Chiudi">
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none"><path d="M6 6l12 12M18 6L6 18" stroke="currentColor" strokeWidth="1.6"/></svg>
        </button>
        <div className="qv-img">
          <div className="qv-box-wrap">
            <div className="product-photo qv-photo">
              {product.image ? (
                <img src={product.image} alt={product.name}
                     onError={(e) => { e.currentTarget.style.display = "none"; const ph = e.currentTarget.parentElement.querySelector('.photo-placeholder'); if (ph) ph.style.display = "flex"; }} />
              ) : null}
              <div className="photo-placeholder" style={{ display: product.image ? "none" : "flex" }}>
                <div className="ph-glyph">{product.glyph || "✦"}</div>
                <div className="ph-franchise">{product.franchise || product.label}</div>
                <div className="ph-name">{product.name}</div>
              </div>
            </div>
          </div>
        </div>
        <div className="qv-info">
          <span className="eyebrow"><span className="dot" />{product.label || "Sealed"}{isPre ? " · Pre-order" : " · Disponibile"}</span>
          <h2>{product.name}</h2>
          <div className="specs">
            <div className="s"><div className="k">Formato</div><div className="v">{product.sub.split("·")[0]?.trim() || "Sealed"}</div></div>
            <div className="s"><div className="k">Confezione</div><div className="v">{product.sub.split("·")[1]?.trim() || "Originale"}</div></div>
            <div className="s"><div className="k">Stato</div><div className="v" style={{ color: soldOut ? "#f5c542" : isPre ? "var(--accent)" : "inherit" }}>{soldOut ? "Esaurito" : isPre ? "Pre-order" : "Disponibile in vault"}</div></div>
            <div className="s"><div className="k">{isPre ? "Uscita" : "Stock"}</div><div className="v">{isPre ? (product.release || "TBA") : (product.stock != null ? `${product.stock} pezzi` : "—")}</div></div>
            <div className="s"><div className="k">Lingua</div><div className="v">Inglese · Italiano</div></div>
            <div className="s"><div className="k">Spedizione</div><div className="v" style={{ color: "var(--accent)" }}>48h corazzata</div></div>
          </div>
          <div className="price">
            <span className="now">€ {typeof product.price === "number" ? product.price.toLocaleString("it-IT") : product.price}</span>
            {!isPre && typeof product.price === "number" && <span className="was">€ {(Math.round(product.price * 1.18)).toLocaleString("it-IT")}</span>}
          </div>
          <div className="qv-cta">
            <button className="btn btn-gold" disabled={soldOut} onClick={() => { if (!soldOut) onAdd(product); }}>
              {soldOut ? "Esaurito" : isPre ? "Prenota nel Vault" : "Aggiungi al Vault"}
              {!soldOut && <svg className="arr" width="14" height="14" viewBox="0 0 24 24" fill="none"><path d="M5 12h14M13 6l6 6-6 6" stroke="currentColor" strokeWidth="1.6"/></svg>}
            </button>
            <button className="btn btn-ghost" onClick={share} title="Copia/condividi il link del prodotto">
              {shared ? "✓ Link copiato" : "Condividi"}
            </button>
          </div>
          {soldOut && (
            <div style={{ marginTop: 14 }}>
              {rState === "ok" ? (
                <div style={{ color: "#22c55e", fontWeight: 600, fontSize: 14 }}>✓ Ti avviseremo via email appena torna disponibile.</div>
              ) : !rOpen ? (
                <button className="btn btn-ghost" style={{ width: "100%", justifyContent: "center" }} onClick={() => setROpen(true)}>
                  🔔 Avvisami quando disponibile
                </button>
              ) : (
                <form onSubmit={submitRestock} style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
                  <input type="email" required placeholder="latua@email.it" value={rEmail} onChange={(e) => setREmail(e.target.value)} className="co-input" style={{ flex: 1, minWidth: 180 }} />
                  <button className="btn btn-gold" type="submit" disabled={rState === "busy"} style={{ justifyContent: "center" }}>{rState === "busy" ? "…" : "Avvisami"}</button>
                  {rState === "err" && <div style={{ color: "#ff6b6b", fontSize: 13, width: "100%" }}>Errore, riprova.</div>}
                </form>
              )}
            </div>
          )}
          <div style={{ display: "flex", gap: 16, marginTop: 16, color: "var(--ink-2)", fontSize: 13, flexWrap: "wrap" }}>
            <span>✦ Sigillato originale</span>
            <span>✦ Spedizione corazzata</span>
            <span>✦ {isPre ? "Prezzo bloccato" : "Reso 14 giorni"}</span>
          </div>
        </div>
      </div>
    </div>
  );
}

function SubscribeModal({ open, onClose }) {
  const [email, setEmail] = React.useState("");
  const [state, setState] = React.useState("");
  React.useEffect(() => { if (open) { setEmail(""); setState(""); } }, [open]);
  async function submit(e) {
    e.preventDefault(); setState("busy");
    const r = await fetch("/api/subscribe", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ email }) }).then((x) => x.json()).catch(() => ({ ok: false }));
    setState(r.ok ? "ok" : "err");
  }
  if (!open) return null;
  return (
    <div className="qv-overlay open" onClick={onClose}>
      <div onClick={(e) => e.stopPropagation()} style={{ width: "min(440px, 100%)", background: "var(--bg-2)", border: "1px solid var(--line-2)", borderRadius: 18, padding: 28, position: "relative" }}>
        <button className="qv-close" onClick={onClose} aria-label="Chiudi" style={{ position: "absolute", top: 14, right: 14 }}>✕</button>
        <h3 style={{ margin: "0 0 8px" }}>Entra nel <em style={{ color: "var(--accent)", fontStyle: "italic" }}>Vault</em></h3>
        <p style={{ color: "var(--ink-2)", fontSize: 14, margin: "0 0 16px" }}>Drop settimanali, priorità sui pre-order e prezzi bloccati. Lascia la tua email.</p>
        {state === "ok" ? (
          <div style={{ color: "#22c55e", fontWeight: 600, padding: "10px 0" }}>✓ Iscrizione registrata. A presto!</div>
        ) : (
          <form onSubmit={submit}>
            <input type="email" required placeholder="latua@email.it" value={email} onChange={(e) => setEmail(e.target.value)} className="co-input" style={{ width: "100%" }} />
            <button className="btn btn-gold" type="submit" disabled={state === "busy"} style={{ justifyContent: "center", width: "100%", marginTop: 12 }}>{state === "busy" ? "…" : "Iscrivimi"}</button>
            {state === "err" && <div style={{ color: "#ff6b6b", fontSize: 13, marginTop: 8 }}>Errore, riprova.</div>}
          </form>
        )}
      </div>
    </div>
  );
}

function SearchOverlay({ open, onClose, onPick }) {
  const [q, setQ] = React.useState("");
  const inputRef = React.useRef(null);
  React.useEffect(() => {
    if (open) { setQ(""); setTimeout(() => inputRef.current && inputRef.current.focus(), 60); }
    function onKey(e) { if (e.key === "Escape" && open) onClose(); }
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [open]);
  const results = React.useMemo(() => {
    const s = q.trim().toLowerCase();
    if (!s) return [];
    const d = window.PC_DATA || {};
    const out = [];
    for (const k of Object.keys(d)) {
      for (const p of (d[k].products || [])) {
        const hay = (p.name + " " + (p.franchise || p.label || "") + " " + (p.sub || "")).toLowerCase();
        if (hay.includes(s)) out.push(p);
        if (out.length >= 40) break;
      }
    }
    return out;
  }, [q, open]);
  if (!open) return null;
  return (
    <div className="search-overlay open" onClick={onClose}>
      <div className="search-panel" onClick={(e) => e.stopPropagation()}>
        <div className="search-bar">
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none"><circle cx="11" cy="11" r="7" stroke="currentColor" strokeWidth="1.6" /><path d="M20 20l-3.5-3.5" stroke="currentColor" strokeWidth="1.6" /></svg>
          <input ref={inputRef} placeholder="Cerca per nome, gioco, set…" value={q} onChange={(e) => setQ(e.target.value)} />
          <button className="search-x" onClick={onClose} aria-label="Chiudi">✕</button>
        </div>
        <div className="search-results">
          {!q.trim() && <div className="search-hint">Scrivi per cercare tra i prodotti del Vault.</div>}
          {q.trim() && results.length === 0 && <div className="search-hint">Nessun prodotto per “{q}”.</div>}
          {results.map((p) => (
            <button key={p.id} className="search-row" onClick={() => onPick(p)}>
              <div className="search-thumb">{p.image ? <img src={p.image} alt="" loading="lazy" /> : <span>✦</span>}</div>
              <div className="search-meta">
                <span className="nm">{p.name}</span>
                <span className="sub">{(p.franchise || p.label || "")}{p.sub ? " · " + p.sub : ""}</span>
              </div>
              <span className="search-pr">{p.price && p.price !== "XXX" ? "€ " + p.price : (p.status === "preorder" ? "Pre-order" : "")}</span>
            </button>
          ))}
        </div>
      </div>
    </div>
  );
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [cartOpen, setCartOpen] = React.useState(false);
  const [items, setItems] = React.useState([]);
  const [quick, setQuick] = React.useState(null);
  const [scrolled, setScrolled] = React.useState(false);
  const [checkoutOpen, setCheckoutOpen] = React.useState(false);
  const [searchOpen, setSearchOpen] = React.useState(false);
  const [subscribeOpen, setSubscribeOpen] = React.useState(false);

  // Apply tokens / flags to <html>
  React.useEffect(() => {
    document.documentElement.setAttribute("data-palette", t.palette || "graphite");
  }, [t.palette]);
  React.useEffect(() => {
    document.documentElement.toggleAttribute("data-no-holo", !t.holoSheen);
  }, [t.holoSheen]);

  // Reveal-on-scroll with stagger
  React.useEffect(() => {
    const io = new IntersectionObserver((entries) => {
      entries.forEach(en => { if (en.isIntersecting) en.target.classList.add("in"); });
    }, { rootMargin: "0px 0px -8% 0px", threshold: 0.08 });
    document.querySelectorAll(".reveal").forEach((el, i) => {
      if (!el.style.getPropertyValue("--i")) {
        // assign stagger index based on the element's index within its parent
        const sibs = Array.from(el.parentElement.children).filter(c => c.classList.contains("reveal"));
        const idx = sibs.indexOf(el);
        if (idx >= 0) el.style.setProperty("--i", idx);
      }
      io.observe(el);
    });
    return () => io.disconnect();
  });

  // Cursor spotlight — fixed glow that follows the mouse on hover-capable devices
  React.useEffect(() => {
    const spot = document.getElementById("cursor-spot");
    if (!spot) return;
    let raf = 0, mx = window.innerWidth / 2, my = window.innerHeight / 2;
    let tx = mx, ty = my;
    function tick() {
      tx += (mx - tx) * 0.18;
      ty += (my - ty) * 0.18;
      spot.style.setProperty("--mx", tx + "px");
      spot.style.setProperty("--my", ty + "px");
      raf = requestAnimationFrame(tick);
    }
    function onMove(e) {
      mx = e.clientX; my = e.clientY;
      spot.classList.add("active");
    }
    function onLeave() { spot.classList.remove("active"); }
    raf = requestAnimationFrame(tick);
    window.addEventListener("mousemove", onMove);
    window.addEventListener("mouseleave", onLeave);
    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener("mousemove", onMove);
      window.removeEventListener("mouseleave", onLeave);
    };
  }, []);

  // Header scrolled state + progress bar
  React.useEffect(() => {
    let raf = 0;
    function onScroll() {
      if (raf) return;
      raf = requestAnimationFrame(() => {
        raf = 0;
        const sc = window.scrollY > 80;
        setScrolled(sc);
        const bar = document.getElementById("progress-bar");
        if (bar) {
          const h = document.documentElement.scrollHeight - window.innerHeight;
          const p = h > 0 ? (window.scrollY / h) * 100 : 0;
          bar.style.width = p + "%";
        }
      });
    }
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);

  // Deep-link: ?p=<product-id> apre la QuickView del prodotto e scrolla alla sezione.
  React.useEffect(() => {
    const id = new URLSearchParams(window.location.search).get("p");
    if (!id || !window.PC_DATA) return;
    let found = null, fk = null;
    for (const k of Object.keys(window.PC_DATA)) {
      const prod = (window.PC_DATA[k].products || []).find((p) => p.id === id);
      if (prod) { found = prod; fk = k; break; }
    }
    if (found) {
      setQuick(found);
      setTimeout(() => document.getElementById(fk)?.scrollIntoView({ behavior: "smooth", block: "start" }), 350);
    }
  }, []);

  function addToCart(p) {
    setItems(prev => {
      const found = prev.findIndex(it => it.id === p.id);
      if (found >= 0) {
        const next = prev.slice();
        next[found] = { ...next[found], qty: next[found].qty + 1 };
        return next;
      }
      return prev.concat([{ ...p, qty: 1 }]);
    });
    // Pulse the cart icon
    const btn = document.getElementById("cart-btn");
    if (btn) { btn.classList.remove("pulse"); void btn.offsetWidth; btn.classList.add("pulse"); }
  }
  function changeQty(idx, delta) {
    setItems(prev => prev.map((it, i) => i === idx ? { ...it, qty: Math.max(1, it.qty + delta) } : it));
  }
  function removeItem(idx) {
    setItems(prev => prev.filter((_, i) => i !== idx));
  }

  function onCta(which) {
    const map = { drops: "ygo", vault: "ygo", graded: "pkm", preorder: "pkm", ygo: "ygo", pkm: "pkm", op: "op" };
    const target = map[which] || "ygo";
    document.getElementById(target)?.scrollIntoView({ behavior: "smooth" });
  }

  return (
    <>
      <div id="cursor-spot" className="cursor-spot" />
      <div id="progress-bar" className="progress" />
      <Header onCart={() => setCartOpen(true)} onSearch={() => setSearchOpen(true)} cartCount={items.reduce((s, i) => s + i.qty, 0)} scrolled={scrolled} />

      <Hero onCta={onCta} tiktok={TIKTOK_URL} wa={WHATSAPP_URL} />

      <BrandStatement />
      <Universes onAdd={addToCart} onQuick={setQuick} />
      <Trust />
      <VaultLive onCta={onCta} onSubscribe={() => setSubscribeOpen(true)} tiktok={TIKTOK_URL} twitch={TWITCH_URL} />
      <Footer />

      <Cart open={cartOpen} items={items} onClose={() => setCartOpen(false)} onQty={changeQty} onRm={removeItem} onCheckout={() => { setCartOpen(false); setCheckoutOpen(true); }} />
      <Checkout open={checkoutOpen} items={items} onClose={() => setCheckoutOpen(false)} onDone={() => setItems([])} />
      {quick && <QuickView product={quick} onClose={() => setQuick(null)} onAdd={(p) => { addToCart(p); setQuick(null); setCartOpen(true); }} />}
      <SearchOverlay open={searchOpen} onClose={() => setSearchOpen(false)} onPick={(p) => { setSearchOpen(false); setQuick(p); }} />
      <SubscribeModal open={subscribeOpen} onClose={() => setSubscribeOpen(false)} />

      <TweaksPanel title="Tweaks">
        <TweakSection label="Palette" />
        <TweakRadio
          label="Tema"
          value={t.palette}
          options={[
            { value: "graphite", label: "Graphite" },
            { value: "obsidian", label: "Obsidian" },
            { value: "violet",   label: "Violet" },
            { value: "ivory",    label: "Ivory" }
          ]}
          onChange={(v) => setTweak("palette", v)}
        />
        <TweakSection label="Hero" />
        <TweakToggle label="Riflesso holofoil sulle carte" value={t.holoSheen} onChange={(v) => setTweak("holoSheen", v)} />
      </TweaksPanel>
    </>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
