/* app.jsx — orchestrator: nav, section assembly, footer, tweaks */
const { useState: aState, useEffect: aEffect } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "hero": "spotlight",
  "accent": "#3a5fae",
  "grain": true
}/*EDITMODE-END*/;

function hexToRgb(h) {
  const m = h.replace('#', '');
  const n = parseInt(m.length === 3 ? m.split('').map((c) => c + c).join('') : m, 16);
  return [(n >> 16) & 255, (n >> 8) & 255, n & 255];
}
function mixBlack(h, amt) {
  const [r, g, b] = hexToRgb(h);
  const f = (x) => Math.round(x * (1 - amt));
  return `rgb(${f(r)},${f(g)},${f(b)})`;
}
function glow(h, a) { const [r, g, b] = hexToRgb(h); return `rgba(${r},${g},${b},${a})`; }
function mixWhite(h, amt) {
  const [r, g, b] = hexToRgb(h);
  const f = (x) => Math.round(x + (255 - x) * amt);
  return `rgb(${f(r)},${f(g)},${f(b)})`;
}

const NAV = [
  { id: 'history', n: '01', label: 'History' },
  { id: 'journey', n: '02', label: 'Journey' },
  { id: 'provenance', n: '03', label: 'Provenance' },
  { id: 'specs', n: '04', label: 'Specs' },
  { id: 'media', n: '05', label: 'Media' },
  { id: 'contact', n: '06', label: 'Contact' },
];

function Nav() {
  const [solid, setSolid] = aState(false);
  const [menuOpen, setMenuOpen] = aState(false);
  const [active, setActive] = aState('');
  const fillRef = React.useRef(null);
  aEffect(() => {
    const on = () => {
      setSolid(window.scrollY > window.innerHeight * 0.7);
      // scroll-spy: the current section is the last one whose top has passed the navbar
      const off = 120;
      let cur = '';
      for (const i of NAV) {
        const el = document.getElementById(i.id);
        if (el && el.getBoundingClientRect().top <= off) cur = i.id;
      }
      setActive(cur);
      // scroll-progress: 0 at the top of the first section, 1 at the page bottom
      const first = document.getElementById(NAV[0].id);
      const top0 = first ? first.offsetTop : 0;
      const total = document.documentElement.scrollHeight - window.innerHeight;
      const p = total > top0 ? Math.min(1, Math.max(0, (window.scrollY - top0) / (total - top0))) : 0;
      if (fillRef.current) fillRef.current.style.width = (p * 100) + '%';
    };
    on(); window.addEventListener('scroll', on, { passive: true });
    return () => window.removeEventListener('scroll', on);
  }, []);
  aEffect(() => {
    const onKey = (e) => { if (e.key === 'Escape') setMenuOpen(false); };
    const onResize = () => { if (window.innerWidth >= 1024) setMenuOpen(false); };
    window.addEventListener('keydown', onKey);
    window.addEventListener('resize', onResize);
    return () => { window.removeEventListener('keydown', onKey); window.removeEventListener('resize', onResize); };
  }, []);
  const barSolid = solid || menuOpen;
  return (
    <nav className="fixed inset-x-0 top-0 z-50 transition-all duration-500"
         style={{ background: barSolid ? 'rgba(10,10,11,0.82)' : 'transparent', backdropFilter: barSolid ? 'blur(14px)' : 'none', borderBottom: barSolid ? '1px solid var(--line)' : '1px solid transparent' }}>
      <div className="mx-auto flex w-full max-w-[1320px] items-center justify-between px-6 py-4 md:px-10">
        <a href="#top" onClick={() => setMenuOpen(false)} className="flex items-baseline gap-3">
          <span className="whitespace-nowrap font-display text-xl uppercase tracking-tight text-ink">The Billy Joel Piano</span>
        </a>
        <div className="flex items-center gap-6 lg:gap-8">
          {NAV.map((i) => (
            <a key={i.id} href={`#${i.id}`} aria-current={active === i.id ? 'page' : undefined} className="group hidden items-baseline gap-1.5 lg:flex">
              <span className={`font-mono text-[10px] transition-colors group-hover:text-[color:var(--accent-text)] ${active === i.id ? 'text-[color:var(--accent-text)]' : 'text-ink-ghost'}`}>{i.n}</span>
              <span className={`text-[13px] uppercase tracking-wide transition-colors group-hover:text-ink ${active === i.id ? 'text-ink' : 'text-ink-dim'}`}>{i.label}</span>
            </a>
          ))}
          {(() => {
            const cur = NAV.find((i) => i.id === active);
            return (
              <span aria-hidden="true"
                    className="flex items-baseline gap-1.5 lg:hidden transition-opacity duration-300"
                    style={{ opacity: cur ? 1 : 0 }}>
                <span className="font-mono text-[10px] text-[color:var(--accent-text)]">{cur?.n}</span>
                <span className="text-[13px] uppercase tracking-wide text-ink">{cur?.label}</span>
              </span>
            );
          })()}
          <button type="button" onClick={() => setMenuOpen((v) => !v)}
                  aria-label="Menu" aria-expanded={menuOpen} aria-controls="mobile-menu"
                  className="grid h-9 w-9 place-items-center border border-white/30 text-ink transition-colors hover:border-white/55 lg:hidden">
            {menuOpen ? (
              <span className="text-lg leading-none">✕</span>
            ) : (
              <svg width="18" height="18" viewBox="0 0 18 18" fill="none" aria-hidden="true">
                <path d="M2 4.5h14M2 9h14M2 13.5h14" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
              </svg>
            )}
          </button>
        </div>
      </div>

      {/* scroll-progress: thin blue fill, shown once the first section is active */}
      <div aria-hidden="true"
           className="pointer-events-none absolute inset-x-0 bottom-0 h-px transition-opacity duration-500"
           style={{ opacity: active ? 1 : 0 }}>
        <div ref={fillRef} className="h-full"
             style={{ width: '0%', background: 'var(--accent)', boxShadow: '0 0 8px var(--accent-glow)', transition: 'width 120ms ease-out' }}></div>
      </div>

      {/* mobile slide-down menu */}
      <div id="mobile-menu" className="overflow-hidden lg:hidden"
           style={{ maxHeight: menuOpen ? 360 : 0, opacity: menuOpen ? 1 : 0,
             pointerEvents: menuOpen ? 'auto' : 'none',
             background: 'rgba(10,10,11,0.96)', backdropFilter: 'blur(14px)',
             borderBottom: menuOpen ? '1px solid var(--line)' : '1px solid transparent',
             transition: 'max-height 420ms cubic-bezier(.16,.84,.36,1), opacity 300ms ease, border-color 300ms ease' }}>
        <div className="mx-auto w-full max-w-[1320px] px-6">
          {NAV.map((i) => (
            <a key={i.id} href={`#${i.id}`} onClick={() => setMenuOpen(false)} aria-current={active === i.id ? 'page' : undefined}
               className="group flex items-baseline gap-3 border-b border-white/[0.06] py-4 last:border-b-0">
              <span className={`font-mono text-[11px] transition-colors group-hover:text-[color:var(--accent-text)] ${active === i.id ? 'text-[color:var(--accent-text)]' : 'text-ink-ghost'}`}>{i.n}</span>
              <span className={`font-display text-lg uppercase tracking-tight transition-colors group-hover:text-ink ${active === i.id ? 'text-ink' : 'text-ink-dim'}`}>{i.label}</span>
            </a>
          ))}
        </div>
      </div>
    </nav>
  );
}

function Footer() {
  return (
    <footer className="border-t border-white/[0.08] bg-black">
      <div className="mx-auto w-full max-w-[1320px] px-6 py-16 md:px-10 md:py-20">
        <div className="flex flex-col gap-10 md:flex-row md:items-end md:justify-between">
          <div>
            <div className="font-display text-[clamp(2rem,5vw,3.6rem)] uppercase leading-[0.95] tracking-tight text-ink">The Billy Joel <span className="chrome">Piano</span></div>
            <p className="mt-4 max-w-[46ch] text-[14.5px] leading-relaxed text-ink-dim">
              1978 Baldwin SF-10 Artist Grand · owned & toured by Billy Joel · 1978–1982. Documented from the archive of record.
            </p>
          </div>
          <dl className="grid grid-cols-2 gap-x-12 gap-y-5">
            {[['Serial', 'SF 223781'], ['Built', '1978'], ['Last played', '12 / 31 / 82'], ['Venue', 'Madison Square Garden']].map(([k, v]) => (
              <div key={k}>
                <dt className="font-mono text-[9.5px] uppercase tracking-[0.26em] text-ink-faint">{k}</dt>
                <dd className="mt-1 font-display text-[1.05rem] tracking-tight text-ink">{v}</dd>
              </div>
            ))}
          </dl>
        </div>
        <div className="mt-14 flex flex-col gap-3 border-t border-white/[0.08] pt-6 font-mono text-[10px] uppercase tracking-[0.22em] text-ink-ghost md:flex-row md:items-center md:justify-between">
          <span>The Billy Joel 1978 Baldwin SF-10 · Digital Archive</span>
        </div>
      </div>
    </footer>
  );
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  useReveal();

  aEffect(() => {
    const r = document.documentElement.style;
    r.setProperty('--accent', t.accent);
    r.setProperty('--accent-deep', mixBlack(t.accent, 0.42));
    r.setProperty('--accent-glow', glow(t.accent, 0.55));
    r.setProperty('--accent-text', mixWhite(t.accent, 0.30));
  }, [t.accent]);

  aEffect(() => {
    document.body.classList.toggle('grain', !!t.grain);
  }, [t.grain]);

  return (
    <div id="top">
      <Nav />

      <main>
        <div data-screen-label="Hero"><Hero variant={t.hero} /></div>
        <div data-screen-label="History"><HistorySection /></div>
        <div data-screen-label="Journey"><Journey /></div>
        <div data-screen-label="Provenance"><Provenance /></div>
        <div data-screen-label="Specs"><Anatomy /></div>
        <div data-screen-label="Media"><Media /></div>
        <div data-screen-label="Contact"><RequestLine /></div>
      </main>

      <Footer />

      <TweaksPanel>
        <TweakSection label="Hero treatment" />
        <TweakRadio label="Layout" value={t.hero}
          options={['spotlight', 'split', 'silhouette']}
          onChange={(v) => setTweak('hero', v)} />

        <TweakSection label="Accent" />
        <TweakColor label="Highlight" value={t.accent}
          options={['#3a5fae', '#3247c4', '#5aa0d6', '#8d96a6']}
          onChange={(v) => setTweak('accent', v)} />

        <TweakSection label="Atmosphere" />
        <TweakToggle label="Film grain" value={t.grain}
          onChange={(v) => setTweak('grain', v)} />
      </TweaksPanel>
    </div>
  );
}

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