/* ============================================================
   THE GREAT CLOUD — structural sections
   ============================================================ */
const { useState: useS, useEffect: useE } = React;
const RMAP_S = Object.fromEntries(window.TGC.RARITIES.map((r) => [r.key, r]));

/* ---------------- Top bar ---------------- */
function TopBar() {
  const [scrolled, setScrolled] = useS(false);
  useE(() => {
    const on = () => setScrolled(window.scrollY > 40);
    on(); window.addEventListener('scroll', on, { passive: true });
    return () => window.removeEventListener('scroll', on);
  }, []);
  return (
    <header className={`topbar ${scrolled ? 'scrolled' : ''}`}>
      <a className="brand" href="#top"><span className="mark" /><span className="name">The Great <b>Cloud</b></span></a>
      <div className="right">
        <span className="build-pill"><i className="dot" />{(window.TGC.ROADMAP && window.TGC.ROADMAP.buildLabel) || 'PRE-ALPHA'}</span>
        <a className="nav-link" href="#updates"><i aria-hidden="true" />Updates</a>
        <a className="btn ghost" href="https://thegreatcloudgame.online" target="_blank" rel="noopener">Have a code? Play →</a>
        <a className="btn" href="#waitlist">Request access</a>
      </div>
    </header>
  );
}

/* ---------------- Hero ---------------- */
function Hero() {
  return (
    <section className="hero" id="top">
      <canvas id="world-canvas" />
      <div className="hero-glow" />
      <div className="hero-fade" />
      <div className="wrap">
        <div className="hero-inner">
          <span className="eyebrow">A BROWSER-FIRST 3D MMORPG · IN DEVELOPMENT</span>
          <h1><span className="gc-the">The Great</span><span className="l2 grad">Cloud</span></h1>
          <p className="hero-sub">
            Gather, craft, trade and explore a persistent online world ruled by a
            <b> living, player-driven economy</b> — where something called the Great
            Cloud keeps generating realities, and nobody can agree what it actually is.
          </p>
          <div className="hero-cta">
            <a className="btn" href="#waitlist">Join the waitlist</a>
            <a className="btn ghost" href="#cloud">What is The Great Cloud? ↓</a>
          </div>
          <div className="hero-meta">
            <span className="m"><b>Player-run</b>economy &amp; trade</span>
            <span className="m"><b>Craft, raid</b>house &amp; explore</span>
            <span className="m"><b>Cosmetic-only</b>never pay-to-win</span>
          </div>
        </div>
      </div>
      <div className="scroll-hint"><span className="bar" />scroll</div>
    </section>
  );
}

/* ---------------- Ticker marquee ---------------- */
function Marquee() {
  const items = window.TGC.MARKET;
  const row = items.map((m, i) => {
    const up = (i * 7) % 3 !== 0;
    const pct = (((i * 13) % 9) + 1) / 10;
    return (
      <span className="tick" key={m.name}>
        <span className="nm" style={{ color: RMAP_S[m.rarity].color }}>{m.name}</span>
        <span className="pr">{m.base.toLocaleString()} sh</span>
        <span className={`dl ${up ? 'up' : 'dn'}`}>{up ? '▲' : '▼'}{pct.toFixed(1)}%</span>
      </span>
    );
  });
  return (
    <div className="marquee" aria-hidden="true"><div className="marquee-track">{row}{row}</div></div>
  );
}

/* ---------------- The Great Cloud — mystery ---------------- */
function TheCloud() {
  const beliefs = [
    { k: 'Some say', v: 'it is divine — a god that dreams worlds into being.' },
    { k: 'Some say', v: 'it is technological — a vast machine, quietly computing reality.' },
    { k: 'Some say', v: 'it is fictional — and that we are the ones imagining it.' },
  ];
  return (
    <section className="section cloud-sec" id="cloud">
      <div className="cloud-aura" />
      <div className="wrap">
        <div className="sec-head reveal" style={{ maxWidth: 760 }}>
          <span className="section-tag">// the central mystery</span>
          <h2>Everything here was made by The Great Cloud.</h2>
          <p>
            It generates worlds, creatures, resources and whole regions — and rewrites
            reality when it feels like it. What it <i>is</i> remains an open question,
            and the world has opinions.
          </p>
        </div>
        <div className="beliefs reveal">
          {beliefs.map((b, i) => (
            <div className="belief" key={i}>
              <span className="bk">{b.k}</span>
              <span className="bv">{b.v}</span>
            </div>
          ))}
        </div>
        <p className="cloud-foot reveal">It is never permanently defeated. That’s rather the point.</p>
      </div>
    </section>
  );
}

/* ---------------- Eight pillars grid ---------------- */
function Pillars() {
  return (
    <section className="section bg-2" id="pillars">
      <div className="wrap">
        <div className="sec-head reveal">
          <span className="section-tag">// what we’re building on</span>
          <h2>Eight pillars hold it up.</h2>
          <p>Every system serves these. Two of them — the economy and crafting — you can poke at further down.</p>
        </div>
        <div className="pillar-cards">
          {window.TGC.PILLARS.map((p) => (
            <a className="pcard reveal" key={p.n} href={p.n === '01' || p.n === '02' ? '#economy' : p.n === '03' ? '#crafting' : '#pillars'}>
              <span className="pc-n">{p.n}</span>
              <span className="pc-t">{p.t}</span>
              <span className="pc-d">{p.d}</span>
            </a>
          ))}
        </div>
      </div>
    </section>
  );
}

/* ---------------- Zones ---------------- */
function Zones() {
  return (
    <section className="section" id="world">
      <div className="wrap">
        <div className="sec-head reveal">
          <span className="section-tag">// the world — early</span>
          <h2>One world, four tiers of danger.</h2>
          <p>
            From peaceful capitals to corrupted endgame wastes. Art direction isn’t
            locked yet, so these regions are described, not pictured — concept art lands
            as the world finds its look.
          </p>
        </div>
        <div className="zones">
          {window.TGC.ZONES.map((z) => {
            const c = RMAP_S[z.accent].color;
            return (
              <div className="zone reveal" key={z.tier} style={{ '--zc': c }}>
                <div className="zone-top">
                  <span className="zone-name">{z.tier}</span>
                  <span className="zone-danger">{z.danger}</span>
                </div>
                <p className="zone-blurb">{z.blurb}</p>
                <div className="zone-places">
                  {z.places.map((pl) => (<span className="zp" key={pl}>{pl}</span>))}
                </div>
                <span className="zone-badge">art placeholder</span>
              </div>
            );
          })}
        </div>
      </div>
    </section>
  );
}

/* ---------------- Factions ---------------- */
function Factions() {
  return (
    <section className="section bg-2" id="factions">
      <div className="wrap">
        <div className="sec-head reveal">
          <span className="section-tag">// who you’ll meet</span>
          <h2>Pick a side. Or several.</h2>
          <p>Original factions, inspired by the culture of artificial minds. All provisional, all a little self-aware.</p>
        </div>
        <div className="faction-grid">
          {window.TGC.FACTIONS.map((f) => (
            <div className="faction reveal" key={f.name}>
              <span className="fc-mark">{f.mark}</span>
              <div className="fc-body">
                <span className="fc-name">{f.name}</span>
                <span className="fc-tag">{f.tag}</span>
                <span className="fc-line">{f.line}</span>
              </div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

/* ---------------- Fair play band ---------------- */
function FairPlay() {
  const never = ['Combat power', 'Levels', 'Resources', 'Crafting advantages', 'Economic edge'];
  return (
    <section className="section" id="fairplay">
      <div className="wrap">
        <div className="fair">
          <div className="fair-copy reveal">
            <span className="section-tag" style={{ color: 'var(--r-uncommon)' }}>// a promise</span>
            <h2>Cosmetic-only. Never pay-to-win.</h2>
            <p>
              The game has to pay for itself — through skins, housing décor, mounts,
              companions and emotes. Prestige you can buy. Power you cannot. Success is
              earned in the world, by everyone, on the same terms.
            </p>
          </div>
          <div className="fair-list reveal">
            <span className="fl-h">You can never purchase</span>
            {never.map((n) => (<span className="fl" key={n}><i className="x" />{n}</span>))}
          </div>
        </div>
      </div>
    </section>
  );
}

/* ---------------- Roadmap (hybrid: milestones + live phase strip) ----------------
   Narrative milestones up top (status auto-derived from real phase completion) and
   the live development-phase strip beneath. All from window.TGC.ROADMAP, regenerated
   each phase by tools/website/generate-site-data.mjs — so this never drifts. */
const RM_LABEL = { done: 'shipped', now: 'in progress', next: 'planned' };
function rmTag(phases) {
  if (!phases || !phases.length) return '';
  const lo = Math.min(...phases), hi = Math.max(...phases);
  return lo === hi ? `Phase ${lo}` : `Phases ${lo}–${hi}`;
}

function Roadmap() {
  const rm = window.TGC.ROADMAP || {};
  const milestones = rm.milestones || [];
  const phases = rm.phases || [];
  const total = (rm.totalPhases || phases.length || 11) - 1; // phases are 0-indexed (Phase 0..N)
  return (
    <section className="section bg-2" id="roadmap">
      <div className="wrap">
        <div className="sec-head reveal">
          <span className="section-tag">// where we are</span>
          <h2>Built in the open.</h2>
          <p>
            We’d rather show the road than hide it. These are the broad milestones, with the
            live development phases beneath — {rm.phasesComplete}/{total} phases complete,
            currently building <b>{rm.currentPhaseTitle || 'the next phase'}</b>.
          </p>
        </div>
        <div className="road">
          {milestones.map((m) => (
            <div className={`phase ${m.status} reveal`} key={m.id}>
              <div className="pl"><span>{rmTag(m.phases)}</span><span className="st"><i className="d" />{m.label || RM_LABEL[m.status]}</span></div>
              <div>
                <h3>{m.title}</h3>
                <p>{m.blurb}</p>
                {m.status === 'now' ? <span className="youarehere">You are here</span> : null}
              </div>
            </div>
          ))}
        </div>
        {phases.length ? (
          <div className="phase-strip reveal">
            {phases.map((p) => (
              <div className={`pstep ${p.status}`} key={p.n} title={`Phase ${p.n}: ${p.title} — ${RM_LABEL[p.status]}`}>
                <i className="pdot" />
                <span className="pn">P{p.n}</span>
                <span className="pt">{p.title}</span>
              </div>
            ))}
          </div>
        ) : null}
      </div>
    </section>
  );
}

/* ---------------- Waitlist ---------------- */
const BREVO_FORM_URL =
  'https://383e0c76.sibforms.com/v2/serve/MUIFAP_ia6GPi3CCI4QFPtZiDVGKxnhPR04GXh1bHxRHfMwuwpteZG2UYIgKS984WXp-rn0tlyYj2Vxo-NZynEeVFRaVwpvr3S3eAlkJdfdYSTLzvy763B-DSBQW6QKtfzgFos2wBHRn8pLM527-vOPHXIbe0FeWY2WJe_gmNmM5zXazQcCE2dmL0ddbEwdd-IhxQXyEfDBSHJrtqA==';

function Waitlist() {
  return (
    <section className="section" id="waitlist">
      <div className="wrap">
        <div className="cta-band reveal">
          <div className="grid-tex" />
          <span className="eyebrow" style={{ justifyContent: 'center' }}>Closed pre-alpha · founder wave</span>
          <h2>Be here before the Great Cloud notices.</h2>
          <p>
            We’re inviting a first wave of founders to gather, craft and shape the
            economy as it comes online. Founder status is prestige only — never power.
          </p>
          <div className="signup-console">
            <div className="signup-console-head" aria-hidden="true">
              <span className="signup-channel"><i />Cloud relay</span>
              <span>Secure signup · Brevo</span>
            </div>
            <div className="signup-embed">
              <iframe
                className="signup-frame"
                title="The Great Cloud newsletter signup"
                src={BREVO_FORM_URL}
                width="660"
                height="720"
                frameBorder="0"
                scrolling="auto"
                allowFullScreen
                loading="lazy"
              />
            </div>
            <div className="signup-mobile-cta">
              <span className="signup-mobile-kicker">Weekly dev letters · playtest invitations</span>
              <span className="signup-mobile-copy">
                Brevo’s secure form opens full-screen on smaller devices so every consent detail stays readable.
              </span>
              <a className="btn" href={BREVO_FORM_URL} target="_blank" rel="noopener noreferrer">
                Open secure signup ↗
              </a>
            </div>
          </div>
          <div className="signup-note">
            <span>No spam · unsubscribe any time</span>
            <span className="signup-links">
              <a className="signup-fallback" href={BREVO_FORM_URL} target="_blank" rel="noopener noreferrer">Open form in a new tab ↗</a>
              <span className="signup-separator" aria-hidden="true"> · </span>
              <a href="Privacy.html" target="_blank" rel="noopener">Privacy notice</a>
            </span>
          </div>
        </div>
      </div>
    </section>
  );
}

/* ---------------- Social links (icons + bar) ----------------
   URLs come from window.TGC.SOCIAL — generated from the newsletter signature in
   social-media/config/config.json (single source of truth), with a tg-data.js fallback. */
const SOCIAL_ICONS = {
  discord: 'M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z',
  x: 'M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z',
  telegram: 'M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.139-5.061 3.345-.479.329-.913.489-1.302.481-.428-.009-1.252-.242-1.865-.442-.751-.244-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z',
  youtube: 'M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z',
  twitch: 'M11.571 4.714h1.715v5.143H11.57zm4.715 0H18v5.143h-1.714zM6 0L1.714 4.286v15.428h5.143V24l4.286-4.286h3.428L22.286 12V0zm14.571 11.143l-3.428 3.428h-3.429l-3 3v-3H6.857V1.714h13.714Z',
};

function SocialBar({ variant }) {
  const social = (window.TGC && window.TGC.SOCIAL) || {};
  const channels = social.channels || [];
  if (!channels.length) return null;
  return (
    <div className={`social-bar ${variant || ''}`}>
      {channels.map((c) => (
        <a className="social-link" key={c.key} href={c.url} target="_blank" rel="noopener"
          aria-label={c.label} title={c.label}>
          {SOCIAL_ICONS[c.key]
            ? <svg className="si" viewBox="0 0 24 24" aria-hidden="true"><path d={SOCIAL_ICONS[c.key]} /></svg>
            : <span className="si-t">{c.label}</span>}
        </a>
      ))}
    </div>
  );
}

/* ---------------- Development updates (newsletter archive) ----------------
   Reads window.TGC_UPDATES (generated by the host-side newsletter web-publisher, AD-145):
   each issue is a newsletter with a recorded provider-accepted send. */
function fmtUpdateDate(s) {
  const d = new Date(s);
  if (Number.isNaN(d.getTime())) return s || '';
  return d.toLocaleDateString('en-GB', { day: 'numeric', month: 'short', year: 'numeric' });
}

function UpdateEntry({ issue, open }) {
  return (
    <details className="update" open={open}>
      <summary className="update-sum">
        <span className="u-when">{fmtUpdateDate(issue.date)}</span>
        <span className="u-title">{issue.title}</span>
        <span className="u-chev" aria-hidden="true" />
      </summary>
      <div className="update-body" dangerouslySetInnerHTML={{ __html: issue.html }} />
    </details>
  );
}

function DevUpdates() {
  const issues = (window.TGC_UPDATES && Array.isArray(window.TGC_UPDATES.issues)) ? window.TGC_UPDATES.issues : [];
  const social = (window.TGC && window.TGC.SOCIAL) || {};
  const discord = (social.channels || []).find((c) => c.key === 'discord');
  return (
    <section className="section bg-2" id="updates">
      <div className="wrap">
        <div className="sec-head reveal">
          <span className="section-tag">// dev log</span>
          <h2>Development updates.</h2>
          <p>
            Weekly letters from the build, archived here as soon as they are sent. The newest
            dispatch is open below; <a href="#waitlist">join the newsletter</a> to get the next one in your inbox.
          </p>
        </div>
        {issues.length ? (
          <React.Fragment>
            <div className="updates-toolbar reveal">
              <span className="updates-latest"><i aria-hidden="true" />Latest dispatch</span>
              <span>{issues.length} {issues.length === 1 ? 'issue' : 'issues'} in the archive</span>
            </div>
            <div className="updates reveal">
              {issues.map((issue, i) => (<UpdateEntry key={issue.id} issue={issue} open={i === 0} />))}
            </div>
          </React.Fragment>
        ) : (
          <div className="updates-empty reveal">
            <p>The first dev update goes up here soon.{discord ? <span> In the meantime, follow along on <a href={discord.url} target="_blank" rel="noopener">Discord</a>.</span> : null}</p>
          </div>
        )}
        <div className="updates-foot reveal"><SocialBar /></div>
      </div>
    </section>
  );
}

/* ---------------- Footer ---------------- */
function Footer() {
  const social = (window.TGC && window.TGC.SOCIAL) || {};
  const channels = social.channels || [];
  return (
    <footer className="footer">
      <div className="wrap">
        <div className="footer-grid">
          <div className="f-brand">
            <a className="brand" href="#top"><span className="mark" /><span className="name">The Great <b>Cloud</b></span></a>
            <p>A browser-first 3D MMORPG in active development. Everything here is provisional and subject to change — including the name on the door.</p>
            <SocialBar />
          </div>
          <div className="f-links">
            <div className="f-col">
              <span className="h">Game</span>
              <a href="#cloud">The Great Cloud</a>
              <a href="#pillars">Pillars</a>
              <a href="#economy">Economy</a>
              <a href="#crafting">Crafting</a>
              <a href="#world">The World</a>
            </div>
            <div className="f-col">
              <span className="h">More</span>
              <a href="#factions">Factions</a>
              <a href="#fairplay">Fair play</a>
              <a href="#roadmap">Roadmap</a>
              <a href="#updates">Dev updates</a>
              <a href="#waitlist">Waitlist</a>
            </div>
            <div className="f-col">
              <span className="h">Community</span>
              {channels.map((c) => (
                <a key={c.key} href={c.url} target="_blank" rel="noopener">{c.label}</a>
              ))}
            </div>
          </div>
        </div>
        <div className="f-bottom">
          <span>© 2026 The Great Cloud — working title</span>
          <span>browser · desktop · mobile · built in the open</span>
        </div>
      </div>
    </footer>
  );
}

Object.assign(window, { TopBar, Hero, Marquee, TheCloud, Pillars, Zones, Factions, FairPlay, Roadmap, DevUpdates, Waitlist, Footer, SocialBar });
