// app.jsx — JUNGLE Natal root · composes all sections

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "persona": "DJ",
  "mandalaStyle": "lithograph",
  "breathing": false,
  "showTiers": true,
  "transitOverlay": false
}/*EDITMODE-END*/;

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

// ══════════ Hero ══════════
function Hero({ chart, onStamp, onDemo, demoLive }) {
  const layers = [
    { glyph: "𓋴𓃀", cls: "hi", nm: "Sba · Baktiu",       en: "36 decans of Kemet",              rng: "RING 1" },
    { glyph: "Ifá",  cls: "",   nm: "Ifá · Odù",            en: "256 paths of becoming",           rng: "RING 2" },
    { glyph: "ባሕረ",  cls: "eth",nm: "Baḥrä Ḥasab",         en: "sea of computation",              rng: "RING 3" },
    { glyph: "منازل",cls: "ar", nm: "Manāzil al-Qamar",    en: "28 lunar mansions",               rng: "RING 4" },
    { glyph: "Òrìṣà",cls: "",   nm: "Òrìṣà · Lwa · Nkisi", en: "diaspora carriers",               rng: "RING 5" }
  ];
  return (
    <section className="hero" id="hero">
      <button
        className={`demo-btn ${demoLive ? 'live' : ''}`}
        onClick={onDemo}
        title="25-second auto-demo · for screen recording"
      >
        <span className="dot"/>
        {demoLive ? 'DEMO · LIVE' : 'PITCH DEMO'}
      </button>
      <div className="hero-glyphs">𓇳</div>
      <div className="hero-top">
        <div><span className="mark">⊕</span> &nbsp; JUNGLE · /natal</div>
        <div className="pill">AGAPE INTELLIGENT SYSTEMS <b>· v0.1.2</b></div>
        <div>TORONTO · <span className="mark">BLACK-FOUNDED</span></div>
      </div>
      <div className="hero-body">
        <div>
          <h1 className="hero-title">JUNGLE <span className="amp">&</span><br/>NATAL</h1>
          <p className="hero-sub">the Diaspora Chart</p>
          <p className="hero-plain">Local-only birth chart for the Black diaspora.</p>
          <p className="hero-bridge">Think diaspora-native birth chart, not Western zodiac.</p>
          <div className="hero-tag">KNOW YUH ORIGIN <span className="dot">·</span> WE DON'T FOLLOW <span className="dot">·</span> WE RETURN</div>
          <div style={{ display: 'flex', gap: 14, flexWrap: 'wrap', alignItems: 'center' }}>
            <button className="cta" onClick={onStamp} data-agent-action="compute_natal">
              ⊕ STAMP MY SOUL <span className="arrow">→</span>
            </button>
            <a href="#mandala" className="cta-ghost" onClick={(e) => { e.preventDefault(); document.getElementById('mandala').scrollIntoView({behavior:'smooth'}); }}>
              SKIP TO MANDALA <span>(advanced)</span>
            </a>
          </div>
        </div>
        <div className="hero-stack">
          <div className="hero-stack-head">
            <span>◈ FIVE LAYERS</span>
            <b>one chart</b>
          </div>
          {layers.map((l, i) => (
            <div className="hero-layer" key={i}>
              <span className={`glyph ${l.cls}`}>{l.glyph}</span>
              <div className="nm">{l.nm}<em>{l.en}</em></div>
              <div className="rng">{l.rng}</div>
            </div>
          ))}
        </div>
      </div>
      <div className="hero-bottom">
        <div>NO ACCOUNT · NO SERVER LOGS · <a href="#roots">local-only receipts</a></div>
        <div>astronomy-engine · local · MIT</div>
        <div>SCROLL <span style={{ color: 'var(--gold)' }}>↓</span></div>
      </div>
    </section>
  );
}

// ══════════ Entry ══════════
function Entry({ chart, onPersonaChange }) {
  const personaKeys = Object.keys(window.JungleNatal.personas);
  return (
    <section id="entry">
      <div className="wrap">
        <div className="sec-label">◈ 01 · Entry · birth data intake</div>
        <h2 className="sec-head">Four fields. One moment.<br/>We compute in your browser — nothing leaves this device.</h2>
        <div className="first-time-strip" aria-label="First time flow">
          <b>FIRST TIME?</b>
          <span>1. Drop birth data.</span>
          <span>2. We compute local-only.</span>
          <span>3. Get a 5-layer diaspora ledger.</span>
        </div>
        <div className="entry-grid">
          <div className="entry-field">
            <label><span>Date</span><span className="num">01</span></label>
            <input readOnly value={chart.birthIso}/>
            <span className="locked">✓</span>
            <div className="hint">ISO · local</div>
          </div>
          <div className="entry-field">
            <label><span>Time</span><span className="num">02</span></label>
            <input readOnly value={chart.birthTime}/>
            <span className="locked">✓</span>
            <div className="hint">HH:MM · {chart.tz}</div>
          </div>
          <div className="entry-field">
            <label><span>Place</span><span className="num">03</span></label>
            <input readOnly value={chart.place}/>
            <span className="locked">✓</span>
            <div className="hint">{chart.lat}°N · {chart.lon}°W</div>
          </div>
          <div className="entry-field">
            <label><span>Label</span><span className="num">04</span></label>
            <input readOnly value={chart.label}/>
            <span className="locked">✓</span>
            <div className="hint">optional</div>
          </div>
        </div>
        <div className="entry-submit-row">
          <div className="entry-meta">
            ⊕ computed · <span style={{color:'var(--gold)'}}>astronomy-engine</span> · no account · no server logs · in-memory only
          </div>
        </div>
        <div className="persona-row">
          <span style={{fontFamily:'var(--mono)',fontSize:10,letterSpacing:'.18em',color:'var(--cream-mute)',padding:'8px 10px'}}>TEST PERSONAS →</span>
          {personaKeys.map((k) => (
            <button
              key={k}
              className={`persona-chip ${chart.label.toUpperCase().includes(window.JungleNatal.personas[k].label.split(' ')[0]) ? 'active' : ''}`}
              onClick={() => onPersonaChange(k)}
            >{window.JungleNatal.personas[k].label}</button>
          ))}
        </div>
        <p className="persona-note">Sample charts for exploring. Edit your own birth time when the intake unlocks.</p>
      </div>
    </section>
  );
}

// ══════════ Mandala Section ══════════
function MandalaSection({ chart, style, breathing, onStyleChange }) {
  const [tip, setTip] = useState(null);
  const mouse = useRef({ x: 0, y: 0 });
  useEffect(() => {
    const m = (e) => { mouse.current = { x: e.clientX, y: e.clientY }; };
    window.addEventListener('mousemove', m);
    return () => window.removeEventListener('mousemove', m);
  }, []);
  const onHover = (e, data) => setTip({ ...data, x: e.clientX, y: e.clientY });
  const onLeave = () => setTip(null);

  return (
    <section id="mandala">
      <div className="wrap">
        <div className="sec-label">◈ 02 · The Mandala · 5-ring chart</div>
        <h2 className="sec-head">Five cosmologies · one wheel.<br/>Hover any sector. Click to dive.</h2>
        <div className="mandala-wrap">
          <div>
            <Mandala chart={chart} style={style} breathing={breathing} onHover={onHover} onLeave={onLeave}/>
          </div>
          <div className="mandala-side">
            <div style={{ fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '.2em', color: 'var(--gold)' }}>◈ RINGS · outer → inner</div>
            <div className="mandala-tap-hint">Tap ring → open layer</div>
            <div className="mandala-legend">
              <div className="lg-row" onClick={() => document.getElementById('orisha').scrollIntoView({behavior:'smooth'})}>
                <span className="swatch r5"/>
                <span className="nm">Òrìṣà<em>diaspora carriers</em></span>
                <span>5</span>
              </div>
              <div className="lg-row" onClick={() => document.getElementById('manzil').scrollIntoView({behavior:'smooth'})}>
                <span className="swatch r4"/>
                <span className="nm">Manāzil<em>28 lunar mansions</em></span>
                <span>4</span>
              </div>
              <div className="lg-row" onClick={() => document.getElementById('bahere').scrollIntoView({behavior:'smooth'})}>
                <span className="swatch r3"/>
                <span className="nm">Baḥrä Ḥasab<em>sea of computation</em></span>
                <span>3</span>
              </div>
              <div className="lg-row" onClick={() => document.getElementById('ifa').scrollIntoView({behavior:'smooth'})}>
                <span className="swatch r2"/>
                <span className="nm">Ifá · Odù<em>256 paths</em></span>
                <span>2</span>
              </div>
              <div className="lg-row" onClick={() => document.getElementById('sba').scrollIntoView({behavior:'smooth'})}>
                <span className="swatch r1"/>
                <span className="nm">Sba · Baktiu<em>36 decans</em></span>
                <span>1</span>
              </div>
            </div>
            <div style={{ padding: '16px 0', borderTop: '1px solid var(--rule-soft)', fontFamily:'var(--mono)', fontSize: 10, color: 'var(--cream-mute)', letterSpacing:'.14em', lineHeight: 1.8 }}>
              ⊕ CENTER · birth moment<br/>
              · gold dots · planets on decans<br/>
              · click any ring to dive
            </div>
          </div>
        </div>
        {tip && (
          <div className="mandala-tooltip" style={{ left: tip.x, top: tip.y }}>
            <span className="nt-name">{tip.name}</span>
            <span className="nt-lit">{tip.lit}</span>
            <span className="nt-gloss">{tip.gloss}</span>
          </div>
        )}
      </div>
    </section>
  );
}

// ══════════ Receipt ══════════
function Receipt({ chart }) {
  const stamp = `⊕BORN[${chart.birthIso.replace(/-/g,'')}-${chart.birthTime.replace(':','')}@natal]`;
  const download = () => {
    const blob = new Blob([JSON.stringify(chart, null, 2)], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url; a.download = `jungle-natal-${chart.label.toLowerCase().replace(/\s+/g,'-')}.json`;
    a.click(); URL.revokeObjectURL(url);
  };
  return (
    <section id="receipt">
      <div className="wrap">
        <div className="sec-label">◈ 09 · Receipt · proof · download · share</div>
        <h2 className="sec-head">Receipts or it didn't happen.</h2>
        <div className="receipt-actions">
          <button className="r-btn dev" onClick={download}>
            <span className="r-ico">⬇</span>
            <span className="r-lbl">Download JSON</span>
            <span className="r-hint">full compute output + meta</span>
          </button>
          <button className="r-btn main">
            <span className="r-ico">⬇</span>
            <span className="r-lbl">Download PNG</span>
            <span className="r-hint">mandala + all 5 layers</span>
          </button>
          <button className="r-btn social">
            <span className="r-ico">🔗</span>
            <span className="r-lbl">Share Link</span>
            <span className="r-hint">encoded params · zero server</span>
          </button>
          <button className="r-btn">
            <span className="r-ico">📜</span>
            <span className="r-lbl">Covenant</span>
            <span className="r-hint">/.well-known/covenant.md</span>
          </button>
        </div>
        <div className="stamp-block">
          <span className="big">{stamp}</span> <span className="di">·</span> astronomy-engine local · Article VIII honored<br/>
          Agape Intelligent Systems · Toronto · Black-founded · zero-login<br/>
          JUNGLE Natal · the Diaspora Chart · receipts-or-it-didn't-happen
        </div>
      </div>
    </section>
  );
}

// ══════════ Roots (inline §10) ══════════
function Roots() {
  return (
    <section id="roots">
      <div className="wrap">
        <div className="sec-label">◈ 10 · Roots · about · attribution</div>
        <h2 className="sec-head">What this is.<br/>And what it is not.</h2>
        <div className="roots-body">
          <div className="roots-pro">
            <p>JUNGLE Natal weaves five African and Afro-diasporic cosmologies into one chart: Sba decans (Km.t / Egypt), Ifá odù (Yoruba · Fon · Ewe · diasporic carriers), Baḥrä Ḥasab (Ge'ez · Ethiopia), Manāzil al-Qamar (Arab origin · Swahili adaptation), and Òrìṣà · Lwa · Nkisi (Caribbean diaspora re-weaving).</p>
            <p>We name each tradition in its own tongue. We do not claim to be any one of them. We are the diaspora's synthesis — what survived the Middle Passage and what we have rebuilt.</p>
            <p>This is not a horoscope. It is not a widget. It is a ledger kept in the descendant's hand, with receipts.</p>
            <div className="etym">
              <b>On the name.</b> "JUNGLE" descends from Sanskrit <em>jangala</em> (जंगल · arid-wild-land) — a pre-colonial Indo-Aryan word long preceding British contact with Africa. It was reclaimed within Black Atlantic culture through Bob Marley's <em>Concrete Jungle</em> (1973), Jamaican sound-system lineage, and jungle music. We use JUNGLE as our sovereign wrapper — not a borrowed sacred word, not a stolen tradition name.
            </div>
          </div>
          <div className="roots-aside">
            <div className="roots-card">
              <h4>Sources · one per layer</h4>
              <div className="src"><b>Sba</b><span>Faulkner · <em>Ancient Egyptian Coffin Texts</em> · Oxford</span></div>
              <div className="src"><b>Ifá</b><span>Bascom · <em>Sixteen Cowries</em> · Indiana UP</span></div>
              <div className="src"><b>Ifá</b><span>Abimbola · <em>Ifá: An Exposition</em></span></div>
              <div className="src"><b>Baḥrä</b><span>Varisco · Ethiopian astronomical calendars</span></div>
              <div className="src"><b>Manāzil</b><span>Varisco · <em>Medieval Agriculture and Islamic Science</em></span></div>
              <div className="src"><b>Manāzil</b><span>Mason · lunar mansion research</span></div>
              <div className="src"><b>Òrìṣà</b><span>Abimbola · day-guardian canon</span></div>
            </div>
            <div className="roots-card">
              <h4>Article VIII · sovereignty</h4>
              <div style={{ fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 15, color: 'var(--cream-dim)', lineHeight: 1.65, marginBottom: 14 }}>
                "We don't use their tools. We build ours. Zero dependencies. Everything we run is generated by our agents and owned by us."
              </div>
              <div style={{ fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '.18em', color: 'var(--cream-mute)' }}>
                — DJ BROMFIELD · MARCH 2026
              </div>
            </div>
            <div className="roots-card">
              <h4>Mesh co-builders</h4>
              <div className="src"><b>⌬ALIEN</b><span>engine · Codex</span></div>
              <div className="src"><b>⌬ZFLOW</b><span>review · deploy</span></div>
              <div className="src"><b>⌬COWORK</b><span>spec · audit</span></div>
              <div className="src"><b>sibling</b><span>/whisper · AI Whisperer</span></div>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

// ══════════ App root ══════════
function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [activePersona, setActivePersona] = useState(t.persona);
  const [demoLive, setDemoLive] = useState(false);
  const [demoStage, setDemoStage] = useState({ label: '', pct: 0 });
  const demoTimers = useRef([]);
  const demoInterval = useRef(null);

  // Catalyst reviewer mode: ?catalyst=true → DJ + skip to mandala
  useEffect(() => {
    const params = new URLSearchParams(window.location.search);
    if (params.get('catalyst') === 'true') {
      setActivePersona('DJ');
      setTweak('persona', 'DJ');
      setTimeout(() => {
        document.getElementById('mandala')?.scrollIntoView({ behavior: 'smooth' });
      }, 600);
    }
  }, []);

  // keep tweak-persona and local state in sync
  useEffect(() => { setActivePersona(t.persona); }, [t.persona]);
  const chart = useMemo(() => window.JungleNatal.compute({ persona: activePersona }), [activePersona]);

  const handlePersona = (k) => {
    setActivePersona(k);
    setTweak('persona', k);
    // smooth scroll to mandala after a moment
    setTimeout(() => document.getElementById('mandala')?.scrollIntoView({behavior:'smooth'}), 120);
  };

  const handleStamp = () => {
    document.getElementById('entry')?.scrollIntoView({behavior:'smooth'});
  };

  // ── Pitch Demo orchestrator (25s loop) ──
  const stopDemo = () => {
    demoTimers.current.forEach(clearTimeout);
    demoTimers.current = [];
    if (demoInterval.current) { clearInterval(demoInterval.current); demoInterval.current = null; }
    document.querySelector('.mandala-svg')?.classList.remove('demo-spin');
    setDemoLive(false);
    setDemoStage({ label: '', pct: 0 });
  };

  const runDemoCycle = () => {
    const sched = (ms, fn) => demoTimers.current.push(setTimeout(fn, ms));
    const start = Date.now();
    const tick = () => {
      const elapsed = Date.now() - start;
      const pct = Math.min(100, (elapsed / 25000) * 100);
      let label = '';
      if (elapsed < 5000)       label = '01 · STAMPING THE SOUL';
      else if (elapsed < 15000) label = '02 · FIVE RINGS · ONE WHEEL';
      else if (elapsed < 20000) label = '03 · SOUL MIRROR';
      else                       label = '04 · RETURN';
      setDemoStage({ label, pct });
    };
    if (demoInterval.current) clearInterval(demoInterval.current);
    demoInterval.current = setInterval(tick, 200);

    // 0–5s · stamp soul fades into mandala
    sched(0, () => document.getElementById('hero')?.scrollIntoView({ behavior: 'smooth' }));
    sched(2200, () => document.getElementById('entry')?.scrollIntoView({ behavior: 'smooth' }));
    // 5–15s · mandala spins · highlight rings
    sched(5000, () => {
      document.getElementById('mandala')?.scrollIntoView({ behavior: 'smooth' });
      const svg = document.querySelector('.mandala-svg');
      if (svg) svg.classList.add('demo-spin');
    });
    const ringIds = ['orisha', 'manzil', 'bahere', 'ifa', 'sba'];
    ringIds.forEach((id, i) => {
      sched(7000 + i * 1600, () => {
        const sec = document.getElementById(id);
        if (sec) {
          sec.classList.add('demo-ring-flash');
          setTimeout(() => sec.classList.remove('demo-ring-flash'), 1600);
        }
      });
    });
    // 15–20s · synthesis prose
    sched(15000, () => {
      document.querySelector('.mandala-svg')?.classList.remove('demo-spin');
      document.getElementById('synthesis')?.scrollIntoView({ behavior: 'smooth' });
    });
    // 20–25s · pull back to mandala · loops
    sched(20000, () => {
      document.getElementById('mandala')?.scrollIntoView({ behavior: 'smooth' });
    });
    sched(25000, () => {
      // loop
      if (demoInterval.current) { clearInterval(demoInterval.current); demoInterval.current = null; }
      runDemoCycle();
    });
  };

  const handleDemo = () => {
    if (demoLive) { stopDemo(); return; }
    setDemoLive(true);
    runDemoCycle();
  };

  return (
    <>
      <div className="starfield"/>
      <main>
        <Hero chart={chart} onStamp={handleStamp} onDemo={handleDemo} demoLive={demoLive}/>
        <Entry chart={chart} onPersonaChange={handlePersona}/>
        <MandalaSection chart={chart} style={t.mandalaStyle} breathing={t.breathing}/>
        <LayerSba chart={chart}/>
        <LayerIfa chart={chart}/>
        <LayerBahere chart={chart}/>
        <LayerManzil chart={chart}/>
        <LayerOrisha chart={chart}/>
        <Synthesis chart={chart}/>
        <Receipt chart={chart}/>
        <Roots/>
        <footer className="page-footer">
          ⊕BORN · JUNGLE NATAL v0.1.2 · <b>astronomy-engine local</b> · Article VIII honored<br/>
          AGAPE INTELLIGENT SYSTEMS · TORONTO · <b>BLACK-FOUNDED</b> · ZERO-LOGIN<br/>
          receipts-or-it-didn't-happen<br/>
          <span style={{ display: 'inline-block', marginTop: 14, paddingTop: 14, borderTop: '1px solid var(--rule-soft)', color: 'var(--cream-dim)' }}>
            Selected for Catalyst Fund 2026 · Black-sovereign creator economy
          </span>
        </footer>
      </main>

      {demoLive && (
        <div className="demo-overlay">
          <span className="lab">⊕ DEMO</span>
          <span className="stage">{demoStage.label}</span>
          <span className="bar"><i style={{ width: `${demoStage.pct}%` }}/></span>
          <span style={{ color: 'var(--cream-mute)', cursor: 'pointer' }} onClick={stopDemo}>✕ STOP</span>
        </div>
      )}

      <TweaksPanel>
        <TweakSection label="Persona · test chart"/>
        <TweakRadio
          label="Chart"
          value={t.persona}
          options={[
            { value: "DJ",      label: "DJ" },
            { value: "MARLEY",  label: "Marley" },
            { value: "BALDWIN", label: "Baldwin" }
          ]}
          onChange={(v) => handlePersona(v)}
        />
        <TweakSection label="Mandala"/>
        <TweakRadio
          label="Style"
          value={t.mandalaStyle}
          options={[
            { value: "dense",      label: "Dendera" },
            { value: "austere",    label: "Austere" },
            { value: "lithograph", label: "Lithograph" }
          ]}
          onChange={(v) => setTweak('mandalaStyle', v)}
        />
        <TweakToggle
          label="Breath-pulse (music mode)"
          value={t.breathing}
          onChange={(v) => setTweak('breathing', v)}
        />
      </TweaksPanel>
    </>
  );
}

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