/* global React, MiniApp, Nav, Hero, ValueProp, PhotoEssay, Features, LocalAI, Founder, Waitlist, Footer */
const { useEffect } = React;

/* ─────────────────────────────────────────────────────────────
   SECTION SWITCHES
   Flip to false to hide a section. The "Writers everywhere" photo
   essay is hidden until real documentary photography is ready —
   set to true once the assets are in place.
   ───────────────────────────────────────────────────────────── */
const SHOW_PHOTO_ESSAY = false;

/* Cinematic pull-quote break — sits between sections for pacing */
function Quote({ body, attr, variant = 'brick' }) {
  const cls = variant === 'brick' ? 'sec-brick' : `sec-${variant}`;
  return (
    <section className={`sec-tight ${cls}`}>
      <div className="container-narrow" style={{ textAlign: 'center' }}>
        <p data-reveal className="quote-body" style={{
          font: '400 clamp(28px, 3.8vw, 44px)/1.25 var(--font-serif-literary)',
          fontStyle: 'italic',
          margin: 0,
          textWrap: 'balance',
          letterSpacing: '-0.005em',
        }}>
          {body}
        </p>
        <p data-reveal data-reveal-delay="1" className="kicker" style={{ marginTop: 24 }}>
          — {attr}
        </p>
      </div>
    </section>
  );
}

function App() {
  // Reveal on scroll — progressive enhancement.
  // We only hide elements AFTER the observer is armed (via .reveal-ready on <html>).
  // Anything already in the viewport on arm is shown immediately.
  useEffect(() => {
    if (!('IntersectionObserver' in window)) return;

    let io;
    const arm = () => {
      const els = document.querySelectorAll('[data-reveal]');
      if (!els.length) return;

      // Immediately reveal anything already on screen so the first paint
      // doesn't flash blank content, then arm the observer for the rest.
      const vh = window.innerHeight;
      els.forEach(el => {
        const rect = el.getBoundingClientRect();
        if (rect.top < vh * 0.95) el.classList.add('in');
      });

      document.documentElement.classList.add('reveal-ready');

      io = new IntersectionObserver((entries) => {
        entries.forEach(e => {
          if (e.isIntersecting) {
            e.target.classList.add('in');
            io.unobserve(e.target);
          }
        });
      }, { threshold: 0.08, rootMargin: '0px 0px -40px 0px' });

      els.forEach(el => { if (!el.classList.contains('in')) io.observe(el); });
    };

    // Wait two frames so all Babel-transpiled child scripts have mounted
    // their section content before we query the DOM.
    const r1 = requestAnimationFrame(() => {
      const r2 = requestAnimationFrame(arm);
      return () => cancelAnimationFrame(r2);
    });

    return () => {
      cancelAnimationFrame(r1);
      if (io) io.disconnect();
    };
  }, []);

  // Scroll progress bar
  useEffect(() => {
    const bar = document.getElementById('scroll-progress');
    if (!bar) return;
    const onScroll = () => {
      const h = document.documentElement;
      const p = h.scrollTop / (h.scrollHeight - h.clientHeight);
      bar.style.width = `${Math.min(100, Math.max(0, p * 100))}%`;
    };
    onScroll();
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);

  return (
    <>
      <div className="scroll-progress" id="scroll-progress"/>
      <Nav/>
      <Hero/>
      <Quote
        body="AI tools to understand your writing, not to write for you."
        attr="Story Builder's Guiding Philosophy"
        variant="terracotta"
      />
      <ValueProp/>
      {SHOW_PHOTO_ESSAY && <PhotoEssay/>}
      <Features/>
      <LocalAI/>
      <Pricing/>
      <Founder/>
      <Waitlist/>
      <Footer/>
    </>
  );
}

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