/* =========================================================================
   Views — Home (stele + observatory), Reader, Module shell
   ========================================================================= */
const { useState: _uS, useEffect: _uE, useRef: _uR } = React;

/* ---------- HERO ---------- */
/* Name temporarily hidden — only the tagline remains, for a lonelier, echoing feel.
   Flip SHOW_HERO_NAME back to true to restore 左锡宁 / Zuo Xining. */
const SHOW_HERO_NAME = false;

function Hero({ lang, ui, identity }) {
  const name = SHOW_HERO_NAME ?
  <h1 className="hero__name">
      <span className="cjk">{identity.cjk}</span>
      <span className="hero__romaji">{identity.romaji}</span>
    </h1> : null;

  const tag = <p className="hero__tag">{ui.tagline}</p>;
  const nameless = SHOW_HERO_NAME ? "" : " hero--nameless";

  return (
    <section className={"hero view" + nameless} data-screen-label="Home · Hero">
      <div className="hero__emblem rise in">
        <Emblem className="emblem--hero" halo />
      </div>
      {name}
      {tag}
      <div className="hero__scroll" aria-hidden="true">
        <span className="line"></span>
      </div>
    </section>);

}

/* ---------- ABOUT (expandable) ---------- */
function About({ lang }) {
  const [open, setOpen] = _uS(false);
  const a = SITE.about[lang];
  const ui = SITE.ui[lang];
  return (
    <section className={"section block about " + (open ? "open" : "")} id="about">
      <div className="wrap col-narrow">
        <SectionHead idx="00" title={ui.about} cjk={lang === "zh"} en={ui.aboutEn} />
        <div className="rise" style={{ marginTop: "var(--s5)" }}>
          <p className="about__lead" lang={lang}>{a.lead}</p>
          <div className="about__more">
            <div>
              <div className="about__body" style={{ paddingTop: "var(--s5)" }}>
                {a.body.map((p, i) => <p key={i} lang={lang}>{p}</p>)}
              </div>
            </div>
          </div>
          <button className="disclosure" onClick={() => setOpen(!open)} aria-expanded={open}>
            {open ? ui.readLess : ui.readMore}
            <Icon.chevron />
          </button>
        </div>
      </div>
    </section>);

}

/* ---------- WRITING ---------- */
function Writing({ lang, go }) {
  const ui = SITE.ui[lang];
  const pieces = SITE.pieces;
  return (
    <section className="section block" id="writing">
      <div className="wrap col-narrow">
        <SectionHead idx="01" title={ui.writing} cjk={lang === "zh"} en={ui.writingEn} />
        <div className="entries rise" style={{ marginTop: "var(--s5)" }}>
          {pieces.map((p) =>
          <a key={p.id} className="entry" onClick={() => go({ view: "reader", id: p.id })} role="button" tabIndex="0"
          onKeyDown={(e) => (e.key === "Enter" || e.key === " ") && go({ view: "reader", id: p.id })}>
              <div className="entry__main">
                <div className="entry__title">{lang === "zh" ? <span className="cjk">{p.title.zh}</span> : p.title.en}</div>
                <div className="entry__dek" lang={lang}>{p.sub[lang]}</div>
              </div>
              <div className="entry__meta">
                {p.date[lang]}
                <span className="tag">{lang === "zh" ? "缘起" : "Colophon"}</span>
              </div>
            </a>
          )}
        </div>
        {/* elegant continuation — intentional space, not "coming soon" */}
        <div className="empty rise" style={{ marginTop: "var(--s6)" }}>
          <Emblem className="empty__watermark" src="assets/emblem-gold-cut.png" alt="" />
          <span className="mono">{lang === "zh" ? "页面以下 · 留白" : "Below · kept blank"}</span>
          <p className="empty__q">
            {lang === "zh" ?
            "其余的，正在生长。这里为还没写下的短文与碎念留好了位置。" :
            "The rest is still growing. Room is kept here for the fragments not yet written."}
          </p>
        </div>
      </div>
    </section>);

}

/* ---------- LAB / modules ---------- */
function Lab({ lang, go }) {
  const ui = SITE.ui[lang];
  const mods = SITE.modules[lang];
  const statusLabel = (s) => ({ dormant: ui.dormant, active: ui.active, planned: ui.planned })[s] || s;
  return (
    <section className="section block" id="lab">
      <div className="wrap" style={{ maxWidth: 980 }}>
        <SectionHead idx="02" title={ui.lab} cjk={lang === "zh"} en={ui.labEn} />
        <p className="rise" style={{ color: "var(--ink-2)", maxWidth: "46ch", marginTop: "var(--s4)", fontFamily: "var(--font-serif)", fontStyle: "italic", fontSize: "var(--t-lead)" }}>
          {ui.labLead}
        </p>
        <div className="modules rise" style={{ marginTop: "var(--s6)" }}>
          {mods.map((m) =>
          <a key={m.id} className={"module module--" + m.status}
          onClick={() => go({ view: "module", id: m.id })} role="button" tabIndex="0"
          onKeyDown={(e) => (e.key === "Enter" || e.key === " ") && go({ view: "module", id: m.id })}>
              <div className="module__top">
                <span className="module__glyph">{m.glyph}</span>
                <span className="module__status">{statusLabel(m.status)}</span>
              </div>
              <div className="module__name">{lang === "zh" ? <span className="cjk">{m.name}</span> : m.name}</div>
              <div className="module__desc" lang={lang}>{m.desc}</div>
              <span className="module__cta">{ui.enter} <Icon.arrowRight /></span>
            </a>
          )}
          <div className="module module--slot" aria-hidden="true">
            <span className="plus">+</span>
            <span className="mono" style={{ letterSpacing: ".14em" }}>{lang === "zh" ? "预留" : "Reserved"}</span>
          </div>
        </div>
      </div>
    </section>);

}

/* ---------- FOOTER ---------- */
function Footer({ lang }) {
  const ui = SITE.ui[lang];
  return (
    <footer className="foot">
      <svg className="foot__ridge" viewBox="0 0 1200 80" preserveAspectRatio="none" aria-hidden="true">
        <path d="M0,72 L150,60 L290,68 L430,40 L560,58 L700,26 L840,52 L980,44 L1120,62 L1200,54" />
      </svg>
      <div className="foot__inner">
        <div className="foot__mark">
          <img src="assets/emblem.png" alt="" />
          <div>
            <div className="foot__seal" style={{ fontSize: 14, color: "var(--ink-2)" }}>{SITE.identity.cjk} · {SITE.identity.romaji}</div>
            <div className="foot__note" style={{ marginTop: 4 }}>{ui.footNote}</div>
          </div>
        </div>
        <div className="foot__note">MMXXVI · 一座向内的小宇宙</div>
      </div>
    </footer>);

}

/* ---------- READER ---------- */
function Reader({ id, lang, go }) {
  const p = SITE.pieces.find((x) => x.id === id) || SITE.pieces[0];
  _uE(() => {window.scrollTo(0, 0);}, [id]);
  const body = p.body[lang];
  return (
    <article className="reader view" data-screen-label={"Reader · " + p.title.en}>
      <div className="reader__inner">
        <button className="back-link" onClick={() => go({ view: "home" }, "writing")}>
          <Icon.arrowLeft /> {SITE.ui[lang].back}
        </button>
        <div className="reader__kicker" style={{ marginTop: "var(--s7)" }}>
          <span className="mono" style={{ color: "var(--primary)" }}>{p.no}</span>
          <span className="mono">{SITE.ui[lang].readingLabel}</span>
        </div>
        <h1 className="reader__title">{lang === "zh" ? <span className="cjk">{p.title.zh}</span> : p.title.en}</h1>
        <p className="reader__sub">{p.sub[lang]}</p>
        <div className="reader__meta">
          <span className="mono">{p.date[lang]}</span>
        </div>
        <hr className="rule" />
        <div className="prose">
          <p className="lead" lang={lang}>{p.lead[lang]}</p>
          {body.map((para, i) => <p key={i} lang={lang}>{para}</p>)}
        </div>
        <div className="colophon">
          <Emblem style={{ width: 40, margin: "0 auto var(--s4)" }} />
          <div className="mono">{SITE.identity.seal} · {lang === "zh" ? "终" : "fin"}</div>
        </div>
      </div>
    </article>);

}

/* ---------- MODULE SHELL (dormant empty state) ---------- */
function ModuleView({ id, lang, go, accentKey }) {
  const ui = SITE.ui[lang];
  const m = SITE.modules[lang].find((x) => x.id === id) || SITE.modules[lang][0];
  _uE(() => {window.scrollTo(0, 0);}, [id]);
  if (m.embed) return <EmbeddedModule m={m} lang={lang} go={go} accentKey={accentKey} />;
  return (
    <section className="reader view" style={{ paddingTop: "var(--s11)" }} data-screen-label={"Module · " + m.id}>
      <div className="wrap" style={{ maxWidth: 760 }}>
        <button className="back-link" onClick={() => go({ view: "home" }, "lab")}>
          <Icon.arrowLeft /> {ui.back}
        </button>
        <div style={{ display: "grid", justifyItems: "center", textAlign: "center", gap: "var(--s5)", marginTop: "var(--s8)" }}>
          <span className="module__glyph" style={{ width: 76, height: 76, fontSize: 38, borderRadius: "var(--r-lg)" }}>{m.glyph}</span>
          <div>
            <div className="reader__title" style={{ fontSize: "var(--t-h2)", whiteSpace: "nowrap", width: "max-content", marginInline: "auto" }}>{lang === "zh" ? <span className="cjk">{m.name}</span> : m.name}</div>
            <div className="module__status" style={{ justifyContent: "center", marginTop: "var(--s4)" }}>{m.status === "planned" ? ui.planned : ui.dormant}</div>
          </div>
          <p className="empty__q" style={{ textAlign: "center", maxWidth: "40ch" }} lang={lang}>{m.desc}</p>
        </div>

        {/* dormant dashboard placeholder — a designed empty state */}
        <div className="empty" style={{ marginTop: "var(--s7)", alignItems: "center", justifyItems: "stretch" }}>
          <Emblem className="empty__watermark" src="assets/emblem-gold-cut.png" alt="" />
          <div style={{ display: "grid", gap: "var(--s4)" }}>
            <div style={{ display: "flex", gap: "var(--s3)", flexWrap: "wrap" }}>
              {[0, 1, 2].map((i) =>
              <div key={i} style={{ flex: "1 1 120px", height: 8, borderRadius: 99, background: "var(--line)" }} />
              )}
            </div>
            <div style={{ height: 1, background: "var(--line-2)" }} />
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "var(--s4)" }}>
              <div style={{ height: 64, borderRadius: "var(--r-md)", border: "1px solid var(--line)", background: "var(--bg)" }} />
              <div style={{ height: 64, borderRadius: "var(--r-md)", border: "1px solid var(--line)", background: "var(--bg)" }} />
            </div>
            <p className="mono" style={{ textAlign: "center", marginTop: "var(--s2)", lineHeight: 1.8 }}>
              {lang === "zh" ? "模块休眠中 · 接入本地 API 后于此苏醒" : "Module dormant · wakes here once the local API is connected"}
            </p>
          </div>
        </div>
      </div>
    </section>);

}

/* ---------- EMBEDDED MODULE (active — self-contained page in an iframe) ---------- */
/* The correlation matrix is a self-contained canvas page. Per its handoff we do not
   touch its script — we only mount it transparently over the site's cosmos and feed
   the site accent into its --accent token, then call its window.refreshTheme(). */
function EmbeddedModule({ m, lang, go, accentKey }) {
  const ui = SITE.ui[lang];
  const ref = _uR(null);
  const [h, setH] = _uS(960);

  const syncHeight = _uR(() => {});
  const applyAccent = _uR(() => {});

  _uE(() => {
    const f = ref.current;if (!f) return;

    syncHeight.current = () => {
      try {
        const doc = f.contentDocument;
        if (doc && doc.body) {
          const ht = Math.max(doc.body.scrollHeight, doc.documentElement.scrollHeight);
          if (ht > 80) setH(ht);
        }
      } catch (e) {}
    };
    applyAccent.current = () => {
      try {
        const win = f.contentWindow, doc = f.contentDocument;
        if (!win || !doc) return;
        const probe = document.createElement("span");
        probe.style.color = getComputedStyle(document.documentElement).getPropertyValue("--primary");
        document.body.appendChild(probe);
        const rgb = getComputedStyle(probe).color;
        probe.remove();
        if (rgb) doc.documentElement.style.setProperty("--accent", rgb);
        if (typeof win.refreshTheme === "function") win.refreshTheme();
      } catch (e) {}
    };

    const onLoad = () => {
      applyAccent.current();
      syncHeight.current();
      // observe inner content so the frame grows when the focus list / provenance expand on click
      try {
        const doc = f.contentDocument, win = f.contentWindow;
        if (doc && doc.body && win && "ResizeObserver" in win) {
          if (f._ro) f._ro.disconnect();
          f._ro = new win.ResizeObserver(() => syncHeight.current());
          f._ro.observe(doc.body);
        }
        // deterministic re-sync: recenter/reset/mode/search all change content height via clicks or Enter
        if (doc && !f._synced) {
          f._synced = true;
          const resync = () => {[60, 260, 520].forEach((d) => setTimeout(() => syncHeight.current(), d));};
          doc.addEventListener("click", resync, true);
          doc.addEventListener("keydown", resync, true);
        }
      } catch (e) {}
      // let Google fonts + layout settle, then relayout the canvas and re-measure
      try {
        const win = f.contentWindow;
        if (win && win.document && win.document.fonts && win.document.fonts.ready) {
          win.document.fonts.ready.then(() => {
            try {win.dispatchEvent(new Event("resize"));} catch (e) {}
            applyAccent.current();syncHeight.current();
          });
        }
      } catch (e) {}
      [150, 500, 1200].forEach((d) => setTimeout(() => {applyAccent.current();syncHeight.current();}, d));
    };

    f.addEventListener("load", onLoad);
    try {if (f.contentDocument && f.contentDocument.readyState === "complete") onLoad();} catch (e) {}

    const onResize = () => {syncHeight.current();};
    window.addEventListener("resize", onResize);
    return () => {
      f.removeEventListener("load", onLoad);
      window.removeEventListener("resize", onResize);
      try {if (f._ro) {f._ro.disconnect();f._ro = null;}} catch (e) {}
    };
  }, [m.embed]);

  // keep the matrix accent in sync with the site's Tweaks accent
  _uE(() => {applyAccent.current();}, [accentKey]);

  return (
    <section className="reader view" style={{ paddingTop: "var(--s10)" }} data-screen-label={"Module · " + m.id}>
      <div className="wrap" style={{ maxWidth: "var(--maxw)" }}>
        <button className="back-link" onClick={() => go({ view: "home" }, "lab")}>
          <Icon.arrowLeft /> {ui.back}
        </button>
        <div className="mod-embed__head rise" style={{ marginTop: "var(--s6)" }}>
          <span className="module__glyph mod-embed__glyph">{m.glyph}</span>
          <div className="mod-embed__heading">
            <div className="mod-embed__name">{lang === "zh" ? <span className="cjk">{m.name}</span> : m.name}</div>
            <div className="module__status module__status--active">{ui.active}</div>
          </div>
        </div>
        <div className="mod-embed rise" style={{ marginTop: "var(--s5)" }}>
          <iframe ref={ref} className="mod-embed__frame" src={m.embed} title={m.name} style={{ height: h }} scrolling="no" />
        </div>
      </div>
    </section>);

}

Object.assign(window, { Hero, About, Writing, Lab, Footer, Reader, ModuleView, EmbeddedModule });