// Moodset — UI primitives & sections
// Loaded via <script type="text/babel">, exposed on window for app.jsx.

const { useState, useEffect, useRef, useMemo } = React;

// ── Reveal on scroll ─────────────────────────────────────────────────────
function Reveal({ children, delay = 0, as: As = 'div', className = '', style, ...rest }) {
  const ref = useRef(null);
  const [shown, setShown] = useState(false);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    if (typeof IntersectionObserver === 'undefined') { setShown(true); return; }
    const io = new IntersectionObserver((entries) => {
      entries.forEach((en) => { if (en.isIntersecting) { setShown(true); io.disconnect(); } });
    }, { threshold: 0.12, rootMargin: '0px 0px -8% 0px' });
    io.observe(el);
    return () => io.disconnect();
  }, []);
  return (
    <As ref={ref} className={`reveal ${shown ? 'in' : ''} ${className}`} data-d={delay || undefined} style={style} {...rest}>
      {children}
    </As>
  );
}

// ── Sticky Nav ──────────────────────────────────────────────────────────
// home=true → use #anchor links. false → links resolve to index.html#anchor.
function Nav({ home = true, current = '' }) {
  const [scrolled, setScrolled] = useState(false);
  const [open, setOpen] = useState(false);

  useEffect(() => {
    const on = () => setScrolled(window.scrollY > 30);
    on();
    window.addEventListener('scroll', on, { passive: true });
    return () => window.removeEventListener('scroll', on);
  }, []);

  useEffect(() => {
    document.body.style.overflow = open ? 'hidden' : '';
    const onKey = (e) => { if (e.key === 'Escape') setOpen(false); };
    window.addEventListener('keydown', onKey);
    return () => { document.body.style.overflow = ''; window.removeEventListener('keydown', onKey); };
  }, [open]);

  const base = home ? '' : 'index.html';
  const brandHref = home ? '#top' : 'index.html';
  const navLinks = [
    { href: 'shop.html',     label: 'Shop',     key: 'shop' },
    { href: 'lighting.html', label: 'Lighting', key: 'lighting' },
    { href: 'desk.html',     label: 'Desk',     key: 'desk' },
    { href: 'cozy.html',     label: 'Cozy',     key: 'cozy' },
    { href: 'decor.html',    label: 'Decor',    key: 'decor' },
    { href: 'about.html',    label: 'About',    key: 'about' },
    { href: 'contact.html',  label: 'Contact',  key: 'contact' },
  ];

  return (
    <React.Fragment>
      <nav className={`nav ${scrolled || !home ? 'scrolled' : ''} ${open ? 'menu-open' : ''}`}>
        <div className="nav-inner">
          <a href={brandHref} className="brand" aria-label="Moodset — home">
            <span className="dot"></span>
            <span>Moodset</span>
          </a>
          <div className="nav-links" aria-label="Primary">
            {navLinks.map((l) => (
              <a key={l.key} href={l.href} aria-current={current === l.key ? 'page' : undefined}>{l.label}</a>
            ))}
          </div>
          <div className="nav-right">
            <a href={`${base}#edit`} className="nav-cta nav-cta-desktop">The Moodset Edit →</a>
            <button
              className="nav-burger"
              aria-label={open ? 'Close menu' : 'Open menu'}
              aria-expanded={open}
              onClick={() => setOpen((v) => !v)}
            >
              <span className="burger" data-open={open}>
                <span></span><span></span><span></span>
              </span>
            </button>
          </div>
        </div>
      </nav>

      <MobileMenu open={open} onClose={() => setOpen(false)} navLinks={navLinks} current={current} base={base} />
    </React.Fragment>
  );
}

// Full-screen mobile takeover
function MobileMenu({ open, onClose, navLinks, current, base }) {
  return (
    <div className={`mnav ${open ? 'mnav-open' : ''}`} aria-hidden={!open}>
      <div className="mnav-veil" onClick={onClose}></div>
      <div className="mnav-panel" role="dialog" aria-modal="true" aria-label="Menu">
        <div className="mnav-head">
          <a href={base || '#top'} className="brand" onClick={onClose}>
            <span className="dot"></span><span>Moodset</span>
          </a>
          <button className="mnav-close" onClick={onClose} aria-label="Close menu">
            <svg width="22" height="22" viewBox="0 0 22 22" stroke="currentColor" strokeWidth="1.5" fill="none">
              <path d="M4 4l14 14M18 4L4 18" />
            </svg>
          </button>
        </div>

        <nav className="mnav-list">
          {navLinks.map((l, i) => (
            <a
              key={l.key}
              href={l.href}
              onClick={onClose}
              className="mnav-link"
              style={{ transitionDelay: open ? `${60 + i * 40}ms` : '0ms' }}
              aria-current={current === l.key ? 'page' : undefined}
            >
              <span className="mnav-num">{String(i + 1).padStart(2,'0')}</span>
              <span className="mnav-lbl serif">{l.label}</span>
              <span className="mnav-arr">→</span>
            </a>
          ))}
        </nav>

        <div className="mnav-foot">
          <div className="mnav-cta-wrap">
            <a href={`${base}#edit`} className="btn" onClick={onClose}>
              The Moodset Edit
              <span className="arr"></span>
            </a>
          </div>
          <div className="mnav-meta">
            <a href="disclosure.html" onClick={onClose}>Affiliate</a>
            <span>·</span>
            <a href="privacy.html" onClick={onClose}>Privacy</a>
          </div>
        </div>
      </div>
    </div>
  );
}

// ── Hero ────────────────────────────────────────────────────────────────
function Hero() {
  return (
    <header className="hero" id="top">
      <div className="hero-img"></div>
      <div className="hero-veil"></div>

      <div className="hero-content">
        <h1 className="display serif">
          Upgrade<br />
          Your <em>Space</em>.
        </h1>

        <p className="lede hero-sub">
          Curated premium finds for better desks, rooms, and moods.
        </p>

        <div className="hero-actions">
          <a href="shop.html" className="btn">
            Shop the Collection
            <span className="arr"></span>
          </a>
        </div>
      </div>

      <div className="hero-foot">
        <span className="scroll"><span>Scroll</span><span className="l"></span></span>
      </div>
    </header>
  );
}

// ── Category card (editorial gateway → dedicated collection page) ─────
function CategoryCard({ num, title, keyword, blurb, href, position }) {
  return (
    <a className="cat cat-rich" href={href} aria-label={`Explore ${title} collection`}>
      <div className="cat-img" style={{ backgroundPosition: position }}></div>
      <div className="cat-amber"></div>
      <div className="cat-veil"></div>
      <div className="cat-body">
        <div className="cat-top">
          <span className="cat-num">{num}</span>
          <span className="cat-kw mono">{keyword}</span>
        </div>
        <div className="cat-bot">
          <h3 className="serif">{title}</h3>
          {blurb && <p className="cat-blurb">{blurb}</p>}
          <span className="cat-cta">
            Explore Collection
            <span className="cat-arr-line"></span>
          </span>
        </div>
      </div>
    </a>
  );
}

function Categories({ items }) {
  return (
    <section className="section" id="categories">
      <div className="container">
        <Reveal className="section-head">
          <div className="titles">
            <span className="section-num">02 / Collections</span>
            <h2 className="h-section serif">Find your <em style={{color:'var(--amber)',fontStyle:'italic'}}>mood</em>.</h2>
          </div>
          <p className="lede" style={{maxWidth:'42ch'}}>
            Four curated lanes. Tap any one to step into its own slow, amber-lit corner of the collection.
          </p>
        </Reveal>

        <div className="cat-grid">
          {items.map((c, i) => (
            <Reveal key={c.key} delay={(i % 4) + 1}>
              <CategoryCard {...c} />
            </Reveal>
          ))}
        </div>
      </div>
    </section>
  );
}

// ── Product placeholder visual ──────────────────────────────────────────
// Generates a moody amber-lit gradient per product so each card feels distinct
// while keeping the brand atmosphere coherent. (User replaces with real shots later.)
function ProductPlaceholder({ seed = 0, category, id }) {
  const palettes = [
    { bg: 'linear-gradient(160deg,#1a1410 0%,#0f0c08 100%)', g: 'rgba(212,146,74,0.55)', gx: '30%', gy: '70%' },
    { bg: 'linear-gradient(140deg,#1d1612 0%,#100c08 100%)', g: 'rgba(232,169,103,0.5)',  gx: '70%', gy: '40%' },
    { bg: 'linear-gradient(180deg,#181410 0%,#0d0a07 100%)', g: 'rgba(196,129,67,0.5)',   gx: '50%', gy: '85%' },
    { bg: 'linear-gradient(200deg,#1b1612 0%,#0f0a07 100%)', g: 'rgba(248,200,138,0.4)',  gx: '20%', gy: '30%' },
    { bg: 'linear-gradient(120deg,#19140f 0%,#0c0907 100%)', g: 'rgba(214,148,80,0.6)',   gx: '75%', gy: '65%' },
    { bg: 'linear-gradient(165deg,#1c1713 0%,#100b08 100%)', g: 'rgba(232,175,116,0.45)', gx: '35%', gy: '55%' },
  ];
  const p = palettes[seed % palettes.length];
  return (
    <React.Fragment>
      <div className="product-img product-img--placeholder" style={{ background: p.bg }}></div>
      <div className="product-glow" style={{ '--gcolor': p.g, '--gx': p.gx, '--gy': p.gy }}></div>
      <div className="product-tex"></div>
      <div className="product-label mono">
        <span className="ph-tag">placeholder</span>
        <span className="ph-id">{id || category}</span>
      </div>
    </React.Fragment>
  );
}

// ── Product card ────────────────────────────────────────────────────────
function ProductCard({ p, idx, fav, onFav }) {
  const ratingNum = p.rating ? parseFloat(p.rating) : null;
  return (
    <article className="product">
      <a
        className={`product-imgwrap ${p.image ? 'product-imgwrap--real' : 'product-imgwrap--placeholder'}`}
        href={p.href}
        target="_blank"
        rel="sponsored nofollow noopener noreferrer"
        aria-label={`View ${p.title} on Amazon`}
      >
        {p.image
          ? <img className="product-img product-img--real" src={p.image} alt={p.title} loading="lazy" />
          : <ProductPlaceholder seed={idx} category={p.tag} id={p.id} />
        }
        {p.tag && <div className="product-tag">{p.tag}</div>}
        <button
          className="product-fav"
          aria-pressed={fav}
          aria-label={fav ? 'Saved' : 'Save'}
          onClick={(e) => { e.preventDefault(); e.stopPropagation(); onFav(p.id); }}
        >
          <svg width="14" height="14" viewBox="0 0 16 16" fill={fav ? 'currentColor' : 'none'} stroke="currentColor" strokeWidth="1.4">
            <path d="M8 14s-5-3.2-5-7.2A2.8 2.8 0 0 1 8 4a2.8 2.8 0 0 1 5 2.8C13 10.8 8 14 8 14z" />
          </svg>
        </button>
      </a>

      <div className="product-body">
        {p.brand && <div className="product-brand mono">{p.brand}</div>}

        <div className="product-head">
          <h3 className="serif">{p.title}</h3>
          {p.price && <span className="price">{p.price}</span>}
        </div>

        {p.hook && <p className="product-hook serif">“{p.hook}”</p>}
        {p.desc && <p className="desc">{p.desc}</p>}

        <div className="product-foot">
          {ratingNum != null && !isNaN(ratingNum) ? (
            <span className="meta">
              <span className="star">★</span> {ratingNum.toFixed(1)}
            </span>
          ) : <span className="meta">{p.brand}</span>}
          <a
            className="product-link"
            href={p.href}
            target="_blank"
            rel="sponsored nofollow noopener noreferrer"
          >
            View Product
            <span className="arr"></span>
          </a>
        </div>
      </div>
    </article>
  );
}

function ProductSkeleton({ idx }) {
  return (
    <article className="product skeleton" aria-hidden="true" style={{ animationDelay: `${idx * 60}ms` }}>
      <div className="product-imgwrap"></div>
      <div className="product-body" style={{gap:14}}>
        <div className="sk-line" style={{width:'70%'}}></div>
        <div className="sk-line short"></div>
        <div className="sk-line" style={{width:'90%',height:10}}></div>
      </div>
    </article>
  );
}

// ── Filter chips ────────────────────────────────────────────────────────
function FilterChips({ filters, active, onChange, counts }) {
  return (
    <div className="chips" role="tablist" aria-label="Filter products by mood">
      {filters.map((f) => (
        <button
          key={f.id}
          className="chip"
          role="tab"
          aria-pressed={active === f.id}
          aria-selected={active === f.id}
          onClick={() => onChange(f.id)}
        >
          {f.label}
          <span className="ct">/ {counts[f.id] ?? 0}</span>
        </button>
      ))}
    </div>
  );
}

// ── Shared: favourites hook ─────────────────────────────────────────────
function useFavs() {
  const [favs, setFavs] = useState(() => {
    try { return new Set(JSON.parse(localStorage.getItem('moodset:favs') || '[]')); }
    catch { return new Set(); }
  });
  const toggleFav = (id) => {
    setFavs((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id); else next.add(id);
      try { localStorage.setItem('moodset:favs', JSON.stringify([...next])); } catch {}
      return next;
    });
  };
  return [favs, toggleFav];
}

// ── ProductGrid (shared by Edit + CollectionView) ──────────────────────
function ProductGrid({ products, density = 'cozy', loading = false, fadeIn = true }) {
  const [favs, toggleFav] = useFavs();
  if (loading) {
    return (
      <div className="products" data-density={density}>
        {Array.from({ length: products.length || 8 }).map((_, i) => (
          <ProductSkeleton key={i} idx={i} />
        ))}
      </div>
    );
  }
  return (
    <div className="products" data-density={density}>
      {products.map((p, i) => {
        const card = <ProductCard p={p} idx={i} fav={favs.has(p.id)} onFav={toggleFav} />;
        return fadeIn ? (
          <Reveal key={p.id} delay={(i % 4) + 1}>{card}</Reveal>
        ) : <React.Fragment key={p.id}>{card}</React.Fragment>;
      })}
    </div>
  );
}

// ── The Moodset Edit (home: curated featured strip, no filters) ────────
function Edit({ products }) {
  const [loading, setLoading] = useState(true);
  useEffect(() => {
    const t = setTimeout(() => setLoading(false), 600);
    return () => clearTimeout(t);
  }, []);
  return (
    <section className="section" id="edit">
      <div className="container">
        <Reveal className="section-head">
          <div className="titles">
            <span className="section-num">03 / The Moodset Edit</span>
            <h2 className="h-section serif">This week's <em style={{color:'var(--amber)',fontStyle:'italic'}}>edit</em>.</h2>
          </div>
          <p className="lede" style={{maxWidth:'42ch'}}>
            A small handful of pieces we'd recommend without hesitation. Each one anchored its category — start here.
          </p>
        </Reveal>

        <ProductGrid products={products} loading={loading} density="cozy" />

        <Reveal>
          <div className="edit-foot">
            <span className="rule-text">Want more? See the full collection</span>
            <div className="edit-foot-links">
              <a href="shop.html">Shop all →</a>
              <a href="lighting.html">Lighting →</a>
              <a href="desk.html">Desk →</a>
              <a href="cozy.html">Cozy →</a>
              <a href="decor.html">Decor →</a>
            </div>
          </div>
        </Reveal>
      </div>
    </section>
  );
}

// ── CollectionView (category-page main: full grid for one category) ────
function CollectionView({ category, products }) {
  const [loading, setLoading] = useState(true);
  useEffect(() => {
    const t = setTimeout(() => setLoading(false), 500);
    return () => clearTimeout(t);
  }, []);
  return (
    <section className="page-section">
      <div className="container">
        <Reveal className="section-head collection-head">
          <div className="titles">
            <span className="section-num mono amber">{category.num} / Collection</span>
            <h2 className="h-section serif" style={{marginTop:14}}>{category.tagline}</h2>
          </div>
          <p className="lede" style={{maxWidth:'46ch'}}>{category.blurb}</p>
        </Reveal>

        <ProductGrid products={products} loading={loading} density="cozy" />
      </div>
    </section>
  );
}

// ── Manifesto ───────────────────────────────────────────────────────────
function Manifesto() {
  return (
    <section className="section manifesto" id="manifesto">
      <div className="container">
        <div className="manifesto-grid">
          <Reveal>
            <span className="eyebrow">04 / The Idea</span>
            <p className="quote serif" style={{marginTop:18}}>
              At Moodset, we curate the kind of pieces that quietly make a room feel <em>better</em> —
              cozier lighting, warmer desks, the small upgrades that change how a space feels at 10pm.
            </p>
            <div className="by">
              <span className="line"></span>
              <span>— The Moodset edit</span>
            </div>
          </Reveal>

          <Reveal delay={2}>
            <div className="pillars">
              <div className="pillar">
                <div className="ix">i.</div>
                <div>
                  <h4>Curated, not catalogued.</h4>
                  <p>The collection is small on purpose. If a piece didn't earn the spot, it's not here.</p>
                </div>
              </div>
              <div className="pillar">
                <div className="ix">ii.</div>
                <div>
                  <h4>Mood over spec sheets.</h4>
                  <p>Lumens matter. Color temperature matters more. We curate for the feeling a piece brings to a room.</p>
                </div>
              </div>
              <div className="pillar">
                <div className="ix">iii.</div>
                <div>
                  <h4>Quietly obsessed over.</h4>
                  <p>Hours go into every pick — we hunt down the pieces that hold up after the trend cycle.</p>
                </div>
              </div>
            </div>
          </Reveal>
        </div>
      </div>
    </section>
  );
}

// ── Footer ──────────────────────────────────────────────────────────────
function Footer({ home = true }) {
  const base = home ? '' : 'index.html';
  return (
    <footer className="foot">
      <div className="container">
        <div className="foot-top">
          <div className="foot-brand">
            <div className="b serif"><span className="dot"></span>Moodset</div>
            <p>Curated premium finds for better desks, rooms, and moods.</p>
            <a href="mailto:hello@shopmoodset.com" className="foot-email">hello@shopmoodset.com</a>
          </div>
          <div className="foot-col">
            <h5>Shop</h5>
            <ul>
              <li><a href={`${base}#lighting`}>Mood Lighting</a></li>
              <li><a href={`${base}#desk`}>Desk Essentials</a></li>
              <li><a href={`${base}#cozy`}>Cozy Accessories</a></li>
              <li><a href={`${base}#decor`}>Room Decor</a></li>
            </ul>
          </div>
          <div className="foot-col">
            <h5>Follow</h5>
            <ul>
              <li><a href="https://www.tiktok.com/@shopmoodset" target="_blank" rel="noopener noreferrer">TikTok · @shopmoodset</a></li>
              <li><a href="https://www.instagram.com/shopmoodset" target="_blank" rel="noopener noreferrer">Instagram · @shopmoodset</a></li>
              <li><a href="https://www.pinterest.com/shopmoodset" target="_blank" rel="noopener noreferrer">Pinterest · @shopmoodset</a></li>
            </ul>
          </div>
          <div className="foot-col">
            <h5>The Brand</h5>
            <ul>
              <li><a href="about.html">About Moodset</a></li>
              <li><a href="contact.html">Contact</a></li>
              <li><a href="disclosure.html">Affiliate Disclosure</a></li>
              <li><a href="privacy.html">Privacy Policy</a></li>
            </ul>
          </div>
        </div>

        <div className="foot-bottom">
          <p className="foot-disclosure">
            As an Amazon Associate, Moodset may earn from qualifying purchases. Links on this page may be affiliate links — using them costs you nothing extra and helps support the curation. <a href="disclosure.html" className="foot-disclosure-link">Read the full disclosure →</a>
          </p>
          <div className="foot-meta">
            <span>© {String(new Date().getFullYear())} Moodset</span>
            <span><span className="heart">●</span> Curated in low light</span>
          </div>
        </div>
      </div>
    </footer>
  );
}

// ── PageHero (compact header for inner pages) ──────────────────────────
function PageHero({ kicker, title, lede, accent = 'Moodset' }) {
  return (
    <header className="phero">
      <div className="phero-img"></div>
      <div className="phero-veil"></div>
      <div className="container phero-content">
        <Reveal>
          <div className="phero-kicker mono">{kicker}</div>
          <h1 className="phero-title serif">{title}</h1>
          {lede && <p className="phero-lede lede">{lede}</p>}
        </Reveal>
      </div>
    </header>
  );
}

// ── PageShell (wraps inner pages with Nav + Footer) ────────────────────
function PageShell({ current, children }) {
  return (
    <React.Fragment>
      <Nav home={false} current={current} />
      <main className="page-main">{children}</main>
      <Footer home={false} />
    </React.Fragment>
  );
}

// ── Prose primitives ───────────────────────────────────────────────────
function Prose({ children }) { return <div className="prose">{children}</div>; }

Object.assign(window, {
  Reveal, Nav, MobileMenu, Hero, Categories, CategoryCard,
  Edit, CollectionView, ProductGrid, useFavs,
  ProductCard, ProductSkeleton, FilterChips,
  Manifesto, Footer, PageHero, PageShell, Prose,
});
