// ── Shared components: nav, footer, primitives ─────────────────────

// Each <script type="text/babel" src="..."> runs in its own scope, so we
// publish React hooks to window for downstream files to pick up.
window.useState    = React.useState;
window.useEffect   = React.useEffect;
window.useRef      = React.useRef;
window.useMemo     = React.useMemo;
window.useCallback = React.useCallback;
const { useState, useEffect, useRef, useMemo, useCallback } = React;

function Brand({ onClick }) {
  return (
    <a href="#" onClick={(e) => { e.preventDefault(); onClick && onClick(); }} className="brand">
      <img className="pm-logo" src="/assets/logo-new.png" alt="PaintMini" />
    </a>
  );
}

// Inline icons (stroke/fill = currentColor so they inherit the surrounding colour).
// Used for nav, quick actions, empty states, and buttons — no emoji anywhere.
function PMIcon({ name, size = 18 }) {
  const base = { width: size, height: size, viewBox: '0 0 16 16', style: { flex: 'none' } };
  const s = { ...base, fill: 'none', stroke: 'currentColor', strokeWidth: 1.5, strokeLinecap: 'round', strokeLinejoin: 'round' };
  const f = { ...base, fill: 'currentColor' };
  switch (name) {
    case 'studio':  return (<svg {...s}><rect x="2" y="2" width="5" height="5" rx="1"/><rect x="9" y="2" width="5" height="5" rx="1"/><rect x="2" y="9" width="5" height="5" rx="1"/><rect x="9" y="9" width="5" height="5" rx="1"/></svg>);
    case 'library': return (<svg {...s}><rect x="2" y="3" width="12" height="10" rx="1.5"/><circle cx="5.5" cy="6.3" r="1"/><path d="M2.6 12l3.4-3 2.4 2 2-1.6 2.6 2"/></svg>);
    case 'paints':  return (<svg {...s}><path d="M8 2c0 0 4.6 4.7 4.6 7.6a4.6 4.6 0 1 1-9.2 0C3.4 6.7 8 2 8 2z"/></svg>);
    case 'credits': return (<svg {...s}><circle cx="8" cy="8" r="6"/><path d="M8 5.2v5.6M6.3 6.7h3.4"/></svg>);
    case 'plus':    return (<svg {...s}><path d="M8 3v10M3 8h10"/></svg>);
    case 'trash':   return (<svg {...s}><path d="M3 4.3h10M6.3 4.3V2.8h3.4v1.5M4.8 4.3l.6 8.4h5.2l.6-8.4"/></svg>);
    case 'check':   return (<svg {...s}><path d="M3.5 8.4l3 3 6-6.8"/></svg>);
    case 'star':    return (<svg {...f}><path d="M8 2l1.6 3.7 4 .35-3 2.6.9 3.9L8 10.5 4.6 12.55l.9-3.9-3-2.6 4-.35z"/></svg>);
    case 'spark':   return (<svg {...f}><path d="M8 1.6l1.1 4 4 1.1-4 1.1L8 11.8 6.9 7.8l-4-1.1 4-1.1z"/></svg>);
    default: return null;
  }
}

const PM_NAV_ITEMS = [
  { key: 'studio',  label: 'Studio',  route: 'studio',  icon: 'studio' },
  { key: 'library', label: 'Library', route: 'library', icon: 'library' },
  { key: 'paints',  label: 'Paints',  route: 'paints',  icon: 'paints' },
  { key: 'credits', label: 'Credits', route: 'credits', icon: 'credits' },
];

// ── Mobile hamburger + slide-in drawer (shown < 820px via CSS) ──────
function PMMobileBar({ navigate, active, credits, onSignOut }) {
  const [open, setOpen] = useState(false);
  useEffect(() => {
    if (!open) return;
    document.body.style.overflow = 'hidden';
    const onKey = (e) => { if (e.key === 'Escape') setOpen(false); };
    document.addEventListener('keydown', onKey);
    return () => { document.body.style.overflow = ''; document.removeEventListener('keydown', onKey); };
  }, [open]);
  const go = (r) => { setOpen(false); navigate(r); };
  const iconBtn = { color: 'inherit', background: 'rgba(246,244,239,0.08)', width: 40, height: 40, borderRadius: 8, display: 'grid', placeItems: 'center', flex: 'none' };
  return (
    <div className="pm-mobilebar">
      <button aria-label="Open menu" onClick={() => setOpen(true)} style={iconBtn}>
        <svg width="20" height="20" viewBox="0 0 20 20" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round"><path d="M3 6h14"/><path d="M3 10h14"/><path d="M3 14h14"/></svg>
      </button>
      <a href="#" onClick={(e) => { e.preventDefault(); go('studio'); }} style={{ display: 'flex' }}>
        <img className="pm-logo pm-logo--dark pm-logo--sm" src="/assets/logo-new.png" alt="PaintMini" style={{ height: 24 }} />
      </a>
      <div style={{ flex: 1 }} />
      <button onClick={() => go('credits')} className="mono" style={{
        display: 'inline-flex', alignItems: 'center', gap: 6, padding: '7px 11px', borderRadius: 100,
        background: 'rgba(246,244,239,0.06)', color: 'var(--sidebar-ink-2)', fontSize: 11, letterSpacing: '0.05em',
      }}>
        <span style={{ width: 6, height: 6, borderRadius: '50%', background: 'var(--brand)' }} />
        {typeof credits === 'number' ? credits : '—'}
      </button>

      {open && (
        <div className="pm-drawer-overlay" onClick={() => setOpen(false)}>
          <aside className="pm-drawer" onClick={(e) => e.stopPropagation()}>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 20 }}>
              <img className="pm-logo pm-logo--dark pm-logo--sm" src="/assets/logo-new.png" alt="PaintMini" style={{ height: 26 }} />
              <button aria-label="Close menu" onClick={() => setOpen(false)} style={{ color: 'var(--sidebar-ink)', width: 34, height: 34, borderRadius: 8, display: 'grid', placeItems: 'center' }}>
                <svg width="18" height="18" viewBox="0 0 18 18" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round"><path d="M4 4l10 10M14 4L4 14"/></svg>
              </button>
            </div>
            <nav className="pm-drawer-nav">
              {PM_NAV_ITEMS.map(it => (
                <a key={it.key} href="#" className={active === it.key ? 'active' : ''}
                   onClick={(e) => { e.preventDefault(); go(it.route); }}>
                  <PMIcon name={it.icon} />{it.label}
                </a>
              ))}
            </nav>
            <div style={{ flex: 1 }} />
            <button className="pm-credit-pill" onClick={() => go('credits')} style={{ width: '100%', marginBottom: 10 }}>
              <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
                <span style={{ width: 6, height: 6, borderRadius: '50%', background: 'var(--brand)' }} />
                {typeof credits === 'number' ? credits : '—'} CREDITS
              </span>
              <span className="pm-credit-add">+</span>
            </button>
            {onSignOut && (
              <button onClick={() => { setOpen(false); onSignOut(); }} style={{
                width: '100%', textAlign: 'left', padding: '11px 12px', borderRadius: 9,
                color: 'var(--sidebar-ink-2)', fontSize: 14, border: '1px solid var(--sidebar-line)',
              }}>Sign out</button>
            )}
          </aside>
        </div>
      )}
    </div>
  );
}

// ── PaintMini dark sidebar shell — used by Studio, Credits, Library ──
function PMSidebar({ navigate, active, user, credits, onSignOut }) {
  const items = PM_NAV_ITEMS;
  const userBtnRef = useRef(null);

  // Mount Clerk's UserButton (with the name shown) at the bottom of the sidebar.
  useEffect(() => {
    const clerk = window.__clerk;
    const el = userBtnRef.current;
    if (!clerk || !el || typeof clerk.mountUserButton !== 'function') return;
    clerk.mountUserButton(el, {
      showName: true,
      afterSignOutUrl: window.location.origin + '/',
      appearance: {
        variables: {
          colorText: '#242424',
          colorTextSecondary: 'rgba(36,36,36,0.6)',
          colorBackground: '#FFFFFF',
          colorPrimary: '#1D3E2F',
        },
        elements: {
          userButtonBox: { flexDirection: 'row', gap: '9px' },
          userButtonOuterIdentifier: { color: '#242424', fontSize: '12.5px', fontWeight: '600' },
          userButtonTrigger: { padding: '4px 8px 4px 4px', borderRadius: '8px', width: '100%', justifyContent: 'flex-start' },
        },
      },
    });
    return () => { try { clerk.unmountUserButton(el); } catch {} };
  }, []);

  return (
    <>
      <aside className="pm-sidebar" data-screen-label="sidebar">
        <a href="#" onClick={(e) => { e.preventDefault(); navigate('studio'); }} className="pm-brand" style={{ marginBottom: 30 }}>
          <img className="pm-logo" src="/assets/logo-new.png" alt="PaintMini" style={{ height: 34 }} />
        </a>
        <nav className="pm-nav">
          {items.map(it => (
            <a key={it.key} href="#"
               className={active === it.key ? 'active' : ''}
               onClick={(e) => { e.preventDefault(); navigate(it.route); }}>
              <PMIcon name={it.icon} /><span className="pm-nav-label">{it.label}</span>
            </a>
          ))}
        </nav>
        <div className="pm-side-spacer"></div>
        <button className="pm-credit-pill" onClick={() => navigate('credits')} style={{ width: '100%' }}>
          <span className="pm-credit-label" style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
            <span style={{ width: 6, height: 6, borderRadius: '50%', background: 'var(--brand)', flex: 'none' }} />
            {typeof credits === 'number' ? credits : '—'} CREDITS
          </span>
          <span className="pm-credit-add">+</span>
        </button>
        {/* Clerk UserButton (avatar + name) at the bottom */}
        <div ref={userBtnRef} className="pm-user" style={{ minHeight: 40 }} />
      </aside>
      <PMMobileBar navigate={navigate} active={active} credits={credits} onSignOut={onSignOut} />
    </>
  );
}

function Nav({ route, navigate, user, credits, onSignOut }) {
  return (
    <nav className="nav" data-screen-label="nav">
      <div className="container nav-inner">
        <Brand onClick={() => navigate(user ? 'studio' : 'landing')} />

        {!user && (
          <div className="nav-links">
            <a href="#features" onClick={(e) => { e.preventDefault(); document.getElementById('features')?.scrollIntoView({ behavior: 'smooth', block: 'start' }); }}>How it works</a>
            <a href="#gallery"  onClick={(e) => { e.preventDefault(); document.getElementById('gallery')?.scrollIntoView({ behavior: 'smooth', block: 'start' }); }}>Gallery</a>
            <a href="#pricing"  onClick={(e) => { e.preventDefault(); document.getElementById('pricing')?.scrollIntoView({ behavior: 'smooth', block: 'start' }); }}>Pricing</a>
          </div>
        )}

        {user && (
          <div className="nav-links">
            <a className={route.name === 'studio' ? 'active' : ''} onClick={(e)=>{e.preventDefault(); navigate('studio');}} href="#">Studio</a>
            <a className={route.name === 'editor' ? 'active' : ''} onClick={(e)=>{e.preventDefault(); navigate('editor');}} href="#">New design</a>
            <a className={route.name === 'credits' ? 'active' : ''} onClick={(e)=>{e.preventDefault(); navigate('credits');}} href="#">Credits</a>
          </div>
        )}

        <div className="nav-spacer"></div>
        <div className="nav-actions">
          {!user && (
            <>
              <button className="btn btn-ghost btn-sm" onClick={() => navigate('auth', { mode: 'signin' })}>Sign in</button>
              <button className="btn btn-gold btn-sm" onClick={() => navigate('auth', { mode: 'signup' })}>Start free</button>
            </>
          )}
          {user && (
            <>
              <CreditsChip credits={credits} onClick={() => navigate('credits')} />
              <UserMenu user={user} onSignOut={onSignOut} navigate={navigate} />
            </>
          )}
        </div>
      </div>
    </nav>
  );
}

function CreditsChip({ credits, onClick }) {
  const low = typeof credits === 'number' && credits < 1;
  return (
    <button
      onClick={onClick}
      title="Credits remaining"
      style={{
        display: 'inline-flex', alignItems: 'center', gap: 8,
        padding: '6px 14px',
        borderRadius: 100,
        border: `1px solid ${low ? 'rgba(200,50,74,0.5)' : 'var(--line-2)'}`,
        background: low ? 'rgba(200,50,74,0.10)' : 'var(--surface)',
        color: low ? 'var(--brand)' : 'var(--ink-2)',
        fontSize: 12.5,
        fontFamily: 'var(--mono)',
        letterSpacing: '0.06em',
        transition: 'all 160ms',
      }}
    >
      <span style={{
        width: 8, height: 8, borderRadius: '50%',
        background: low ? 'var(--brand)' : 'var(--gold)',
      }}/>
      {typeof credits === 'number' ? credits : '—'} CREDIT{credits === 1 ? '' : 'S'}
    </button>
  );
}

function UserMenu({ user, onSignOut, navigate }) {
  const [open, setOpen] = useState(false);
  const ref = useRef(null);
  useEffect(() => {
    function onDoc(e) { if (!ref.current?.contains(e.target)) setOpen(false); }
    document.addEventListener('mousedown', onDoc);
    return () => document.removeEventListener('mousedown', onDoc);
  }, []);
  const initials = user.name.split(' ').map(w => w[0]).slice(0,2).join('');
  return (
    <div ref={ref} style={{ position: 'relative' }}>
      <button className="user-chip" onClick={() => setOpen(o => !o)}>
        <span className="avatar">{initials}</span>
        <span className="avatar-name">{user.name.split(' ')[0]}</span>
      </button>
      {open && (
        <div className="card" style={{
          position: 'absolute', top: 'calc(100% + 8px)', right: 0,
          width: 240, padding: '8px', zIndex: 100,
          boxShadow: '0 24px 48px -12px rgba(0,0,0,0.6)',
        }}>
          <div style={{ padding: '10px 12px 12px', borderBottom: '1px solid var(--line)' }}>
            <div style={{ fontFamily: 'var(--serif)', fontSize: 17, fontWeight: 600 }}>{user.name}</div>
            <div style={{ fontSize: 12, color: 'var(--ink-3)' }}>{user.email}</div>
          </div>
          {[
            ['Studio', () => navigate('studio')],
            ['Paint library', null],
            ['Account', null],
            ['Billing', null],
          ].map(([label, fn]) => (
            <button key={label}
              onClick={() => { fn?.(); setOpen(false); }}
              style={{
                display: 'block', width: '100%', textAlign: 'left',
                padding: '9px 12px', borderRadius: 8, fontSize: 13.5, color: 'var(--ink-2)'
              }}
              onMouseEnter={(e) => e.currentTarget.style.background = 'var(--surface-2)'}
              onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
            >{label}</button>
          ))}
          <hr className="hair" style={{ margin: '6px 0' }} />
          <button
            onClick={() => { setOpen(false); onSignOut(); }}
            style={{
              display: 'block', width: '100%', textAlign: 'left',
              padding: '9px 12px', borderRadius: 8, fontSize: 13.5, color: 'var(--ink-2)'
            }}
            onMouseEnter={(e) => e.currentTarget.style.background = 'var(--surface-2)'}
            onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
          >Sign out</button>
        </div>
      )}
    </div>
  );
}

function Footer() {
  return (
    <footer className="foot">
      <div className="container foot-inner">
        <div>
          <div className="brand" style={{ marginBottom: 8 }}>
            <img className="pm-logo" src="/assets/logo-new.png" alt="PaintMini" />
          </div>
          <div className="foot-meta">
            A studio assistant for tabletop painters.<br/>
            Made with cold tea, warm brushes, and very small brushes.
          </div>
        </div>
        <div className="foot-cols">
          <div className="foot-col">
            <h5>Product</h5>
            <a href="#">How it works</a>
            <a href="#">Gallery</a>
            <a href="#">Pricing</a>
            <a href="#">Roadmap</a>
          </div>
          <div className="foot-col">
            <h5>Library</h5>
            <a href="#">Citadel</a>
            <a href="#">Vallejo</a>
            <a href="#">Scale75</a>
            <a href="#">Custom mixes</a>
          </div>
          <div className="foot-col">
            <h5>Studio</h5>
            <a href="#">Tutorials</a>
            <a href="#">Discord</a>
            <a href="#">Changelog</a>
            <a href="#">Press kit</a>
          </div>
        </div>
      </div>
      <div className="container" style={{ marginTop: 32, display: 'flex', justifyContent: 'space-between', color: 'var(--ink-4)', fontSize: 11, fontFamily: 'var(--mono)' }}>
        <span>© 2026 MINIATURES STUDIO ⸺ ALL PAINTS ARE TRADEMARKS OF THEIR RESPECTIVE OWNERS</span>
        <span>BUILT IN A WORKSHOP, FAR FROM THE CLOUD</span>
      </div>
    </footer>
  );
}

// Reusable swatch grid (decorative ribbon)
function SwatchRibbon({ colours, height = 8, gap = 3 }) {
  return (
    <div style={{ display: 'flex', gap, height }}>
      {colours.map((c, i) => (
        <div key={i} style={{
          flex: 1, background: c,
          borderRadius: 2,
          boxShadow: 'inset 0 0 0 1px rgba(0,0,0,0.2)',
        }}/>
      ))}
    </div>
  );
}

// A painted figure placeholder card — used in landing + studio
function FigureFrame({ project, height = 260, dim = false }) {
  const tint = project.accent;
  return (
    <div style={{
      position: 'relative',
      height,
      borderRadius: 'var(--r-md)',
      overflow: 'hidden',
      background: 'var(--surface-2)',
    }}>
      {project.image ? (
        <img
          src={project.image}
          alt={project.name}
          style={{
            position: 'absolute', inset: 0,
            width: '100%', height: '100%',
            objectFit: 'cover',
            display: 'block',
          }}
        />
      ) : (
        <div style={{
          position: 'absolute', inset: 0,
          background:
            `repeating-linear-gradient(135deg, rgba(237,230,216,0.04) 0 8px, transparent 8px 16px),` +
            `radial-gradient(ellipse at 50% 80%, ${tint}22, transparent 60%),` +
            `linear-gradient(180deg, var(--surface-2), var(--surface))`,
        }}>
          <div style={{
            position: 'absolute', left: '50%', bottom: '14%',
            transform: 'translateX(-50%)',
          }}>
            <Silhouette kind={project.silhouette} size={Math.max(80, height * 0.34)} color={dim ? 'rgba(237,230,216,0.10)' : project.palette[0]} />
          </div>
        </div>
      )}

      {/* Soft top→bottom gradient for legibility */}
      <div style={{
        position: 'absolute', inset: 0,
        background: `linear-gradient(180deg, rgba(15,13,11,0.0) 50%, rgba(15,13,11,0.55) 100%)`,
        pointerEvents: 'none',
      }}/>

      {/* paint streaks */}
      <div style={{
        position: 'absolute', right: 12, top: 12,
        display: 'flex', flexDirection: 'column', gap: 4,
      }}>
        {project.palette.slice(0, 5).map((c, i) => (
          <div key={i} style={{
            width: 22, height: 4, background: c,
            borderRadius: 1,
            boxShadow: 'inset 0 0 0 1px rgba(0,0,0,0.2), 0 1px 4px rgba(0,0,0,0.4)',
          }}/>
        ))}
      </div>
    </div>
  );
}

Object.assign(window, { Nav, Footer, Brand, SwatchRibbon, FigureFrame });
