/* =========================================================
   stages.jsx — the seven waypoints + closing receipt.
   StageView dispatches by waypoint id. StageShell frames each.
   ========================================================= */

const GATE = {
  listening: "Optional — mark the signals that land, then continue whenever you like.",
  framing: "Optional — mark a framing, or simply move on.",
  envisioning: "Optional — mark the signals that matter, or move on.",
  assumptions: "Optional — mark the riskiest belief, or move on.",
  transformation: "Optional — set the markers, or move on.",
  crux: "Optional — mark a crux, or move on.",
  integration: "Optional — note what now feels obvious to close the loop.",
};

/* ---------- arrival header + gated advance ---------- */
function StageShell({ w, idx, children }) {
  const s = window.useJourney();
  const complete = s.stageComplete(w.id);
  const last = idx === s.WPS.length - 1;
  const next = !last ? s.WPS[idx + 1] : null;
  const [n1, n2] = w.coord.split(" · ");

  return (
    <div className="stage__inner">
      <Reveal as="header" className="arrival">
        <div className="arrival__coord">
          <span>{n1}</span><span className="dash" /><span>{n2}</span>
        </div>
        <h1 className="arrival__title">{w.title}</h1>
        <p className="arrival__lede">{w.lede}</p>
        <Questions items={w.questions} />
      </Reveal>

      <Reveal>
        <div className={`note ${w.id === "crux" ? "note--signal" : ""}`} style={{ marginTop: "var(--sp-6)" }}>
          {w.arrival}
        </div>
      </Reveal>

      {children}

      <Reveal as="footer" className="advance">
        <div className="advance__meta">
          {last ? (
            <>
              <div className="advance__next">End of the trail</div>
              <div className="advance__nexttitle">The overlook</div>
            </>
          ) : (
            <>
              <div className="advance__next">Next waypoint · {next.num}</div>
              <div className="advance__nexttitle">{next.title}</div>
            </>
          )}
          {!complete && <div className="advance__hint">{GATE[w.id]}</div>}
        </div>
        {last ? (
          <button className="btn btn--primary" onClick={() => s.goTo("home")}>
            Close the walk
            <Icon name="check" size={18} />
          </button>
        ) : (
          <button className="btn btn--primary" onClick={() => s.goTo(idx + 1)}>
            Continue down the trail
            <span className="arrow"><Icon name="arrow" size={18} /></span>
          </button>
        )}
      </Reveal>
    </div>
  );
}

/* ---------- 01 LISTENING ---------- */
function Listening({ w }) {
  const s = window.useJourney();
  const m = s.marks.listening;
  const toggle = (i, tag) => s.setMark("listening", (st) => {
    const signals = { ...(st.signals || {}) };
    const cur = signals[i] || [];
    signals[i] = cur.includes(tag) ? cur.filter((t) => t !== tag) : [...cur, tag];
    if (!signals[i].length) delete signals[i];
    return { ...st, signals };
  });
  return (
    <>
      <Reveal as="section" className="section">
        <SectionHead>The signals · read slowly, mark freely</SectionHead>
        <div className="signal-grid">
          {w.signals.map((sig, i) => (
            <SignalCard key={i} data={sig} marks={m.signals?.[i]} onToggle={(tag) => toggle(i, tag)} />
          ))}
        </div>
      </Reveal>
      <Reveal>
        <div className="pull" style={{ marginTop: "var(--sp-7)" }}>{w.reflection}</div>
      </Reveal>
      <Reveal as="section" className="section">
        <SectionHead>Your read</SectionHead>
        <TextMark
          label={w.prompt.label} placeholder={w.prompt.placeholder}
          value={m.note} onChange={(v) => s.setMark("listening", { note: v })}
          hint="Saved to the ledger the moment you type."
        />
      </Reveal>
    </>
  );
}

/* ---------- 02 FRAMING ---------- */
function Framing({ w }) {
  const s = window.useJourney();
  const m = s.marks.framing;
  return (
    <>
      <Reveal>
        <div className="pull" style={{ marginTop: "var(--sp-7)" }}>{w.pull}</div>
      </Reveal>
      <Reveal as="section" className="section">
        <SectionHead>What deserves attention · choose one</SectionHead>
        <div className="choices">
          {w.frames.map((f, i) => (
            <Choice key={i} radio on={m.frame === i} title={f.t} desc={f.d} more={f.more}
              onSelect={() => s.setMark("framing", { frame: m.frame === i ? null : i })} />
          ))}
        </div>
      </Reveal>
      <Reveal as="section" className="section">
        <SectionHead>Name it</SectionHead>
        <TextMark label={w.prompt.label} placeholder={w.prompt.placeholder}
          value={m.note} onChange={(v) => s.setMark("framing", { note: v })} />
      </Reveal>
      <Reveal>
        <div className="note" style={{ marginTop: "var(--sp-6)" }}>{w.reflection}</div>
      </Reveal>
    </>
  );
}

/* ---------- 03 ENVISIONING ---------- */
function Envisioning({ w }) {
  const s = window.useJourney();
  const m = s.marks.envisioning;
  const toggle = (i) => s.setMark("envisioning", (st) => {
    const cur = st.signals || [];
    return { ...st, signals: cur.includes(i) ? cur.filter((x) => x !== i) : [...cur, i] };
  });
  return (
    <>
      <Reveal>
        <div style={{ marginTop: "var(--sp-7)" }}>
          <div className="section__eyebrow"><span>The vision in one sentence</span><span className="dash" /></div>
          <div className="vision-line">{w.visionLine}</div>
        </div>
      </Reveal>
      <Reveal as="section" className="section">
        <SectionHead>Signals you’d accept as proof of arrival · select any</SectionHead>
        <div className="choices">
          {w.arrivalSignals.map((a, i) => (
            <Choice key={i} on={(m.signals || []).includes(i)} title={a.t} group={a.g} more={a.more}
              onSelect={() => toggle(i)} />
          ))}
        </div>
      </Reveal>
      <Reveal as="section" className="section">
        <SectionHead>Paint the future state</SectionHead>
        <TextMark label={w.prompt.label} placeholder={w.prompt.placeholder}
          value={m.note} onChange={(v) => s.setMark("envisioning", { note: v })} />
      </Reveal>
      <Reveal>
        <div className="pull" style={{ marginTop: "var(--sp-7)" }}>{w.reflection}</div>
      </Reveal>
    </>
  );
}

/* ---------- 04 ASSUMPTIONS ---------- */
function Assumptions({ w }) {
  const s = window.useJourney();
  const m = s.marks.assumptions;
  return (
    <>
      <Reveal as="section" className="section">
        <SectionHead>What must be true · mark the riskiest belief</SectionHead>
        <div className="choices">
          {w.assumptions.map((a, i) => (
            <Choice key={i} radio on={m.riskiest === i} title={a.t} desc={a.c} more={a.more}
              rank={m.riskiest === i ? "riskiest" : ""}
              onSelect={() => s.setMark("assumptions", { riskiest: m.riskiest === i ? null : i })} />
          ))}
        </div>
      </Reveal>
      <Reveal as="section" className="section">
        <SectionHead>The disconfirming test</SectionHead>
        <TextMark label={w.prompt.label} placeholder={w.prompt.placeholder}
          value={m.note} onChange={(v) => s.setMark("assumptions", { note: v })} />
      </Reveal>
      <Reveal>
        <div className="note note--signal" style={{ marginTop: "var(--sp-6)" }}>{w.reflection}</div>
      </Reveal>
    </>
  );
}

/* ---------- 05 TRANSFORMATION ---------- */
function Transformation({ w }) {
  const s = window.useJourney();
  const m = s.marks.transformation;
  const change = (i, val) => s.setMark("transformation", (st) => ({
    ...st, touched: true, scales: { ...(st.scales || {}), [i]: val },
  }));
  return (
    <>
      <Reveal>
        <div className="note" style={{ marginTop: "var(--sp-6)" }}>
          <strong style={{ fontWeight: 700 }}>Solid marker</strong> is where each thing stands today.
          <strong style={{ fontWeight: 700 }}> Open marker</strong> is where it must stand tomorrow.
          The coloured distance between them is the work.
        </div>
      </Reveal>
      <Reveal as="section" className="section">
        <SectionHead>The crossing · set today and tomorrow</SectionHead>
        <div className="scales">
          {w.scales.map((sc, i) => (
            <ScaleRow key={i} data={sc} value={m.scales?.[i]} onChange={(val) => change(i, val)} />
          ))}
        </div>
      </Reveal>
      <Reveal as="section" className="section">
        <SectionHead>The decisive gap</SectionHead>
        <TextMark label={w.prompt.label} placeholder={w.prompt.placeholder}
          value={m.note} onChange={(v) => s.setMark("transformation", { note: v })} />
      </Reveal>
      <Reveal>
        <div className="pull" style={{ marginTop: "var(--sp-7)" }}>{w.reflection}</div>
      </Reveal>
    </>
  );
}

/* ---------- 06 CRUX ---------- */
function Crux({ w }) {
  const s = window.useJourney();
  const m = s.marks.crux;
  return (
    <>
      <Reveal>
        <div className="pull note--signal" style={{ marginTop: "var(--sp-7)", borderLeftColor: "var(--signal)" }}>{w.pull}</div>
      </Reveal>
      <Reveal as="section" className="section">
        <SectionHead>The one that unlocks the rest · choose deliberately</SectionHead>
        <div className="choices">
          {w.cruxes.map((c, i) => (
            <Choice key={i} radio on={m.crux === i} title={c.t} desc={c.d} rank={c.rank} more={c.more}
              onSelect={() => s.setMark("crux", { crux: m.crux === i ? null : i })} />
          ))}
        </div>
      </Reveal>
      <Reveal as="section" className="section">
        <SectionHead>In your own words</SectionHead>
        <TextMark label={w.prompt.label} placeholder={w.prompt.placeholder}
          value={m.note} onChange={(v) => s.setMark("crux", { note: v })} />
      </Reveal>
      <Reveal>
        <div className="pull" style={{ marginTop: "var(--sp-7)" }}>{w.reflection}</div>
      </Reveal>
    </>
  );
}

/* ---------- the RECEIPT (closing artifact) ---------- */
function hashMarks(marks) {
  const str = JSON.stringify(marks);
  let h = 0x811c9dc5;
  for (let i = 0; i < str.length; i++) { h ^= str.charCodeAt(i); h = (h * 0x01000193) >>> 0; }
  const hex = ("00000000" + h.toString(16)).slice(-8);
  return `${hex.slice(0,4)}-${hex.slice(4,8)}-${("0000"+(str.length%65536).toString(16)).slice(-4)}`;
}

function buildReceiptRows(marks) {
  const J = window.JOURNEY;
  const g = (id) => marks[id] || {};
  const rows = [];
  // 01
  const lis = g("listening");
  const nMarked = Object.values(lis.signals || {}).filter((a) => a && a.length).length;
  rows.push({ k: "01 · Heard", v: (lis.note || "").trim() || `${nMarked} signal${nMarked === 1 ? "" : "s"} marked as important or surprising`, em: !!(lis.note || "").trim() });
  // 02
  const fr = g("framing");
  rows.push({ k: "02 · Framed", v: fr.frame != null ? J.waypoints[1].frames[fr.frame].t : "—" });
  // 03
  const en = g("envisioning");
  rows.push({ k: "03 · Aiming for", v: (en.note || "").trim() || `${(en.signals||[]).length} signal(s) of arrival chosen`, em: !!(en.note || "").trim() });
  // 04
  const as = g("assumptions");
  rows.push({ k: "04 · Riskiest belief", v: as.riskiest != null ? J.waypoints[3].assumptions[as.riskiest].t : "—" });
  // 05
  const tr = g("transformation");
  let big = "—";
  if (tr.scales && Object.keys(tr.scales).length) {
    let maxGap = -1, name = "";
    Object.entries(tr.scales).forEach(([i, val]) => {
      const sc = J.waypoints[4].scales[i];
      const gap = Math.abs((val.tomorrow ?? sc.tomorrow) - (val.today ?? sc.today));
      if (gap > maxGap) { maxGap = gap; name = `${sc.name} · ${val.today ?? sc.today}→${val.tomorrow ?? sc.tomorrow}`; }
    });
    big = name;
  } else if (tr.touched) big = "markers placed at defaults";
  rows.push({ k: "05 · Widest gap", v: (tr.note || "").trim() || big, em: !!(tr.note || "").trim() });
  // 06
  const cx = g("crux");
  rows.push({ k: "06 · The crux", v: (cx.note || "").trim() || (cx.crux != null ? J.waypoints[5].cruxes[cx.crux].t : "—"), em: true });
  // 07
  const ig = g("integration");
  rows.push({ k: "07 · Now obvious", v: (ig.note || "").trim() || "—", em: true });
  return rows;
}

function Receipt() {
  const s = window.useJourney();
  const rows = buildReceiptRows(s.marks);
  const allDone = s.WPS.every((w) => s.stageComplete(w.id));
  const date = new Date().toLocaleDateString("en-US", { year: "numeric", month: "short", day: "numeric" });
  return (
    <div className="receipt" id="receipt">
      <div className="receipt__top">
        <div className="receipt__mark">Receipt of thinking</div>
        <div className="receipt__title">No receipt, no belief.</div>
        <div className="receipt__meta">{window.JOURNEY.subject} · {window.JOURNEY.session} · {date}</div>
      </div>
      <div className="receipt__rows">
        {rows.map((r, i) => (
          <div className="receipt-row" key={i}>
            <span className="receipt-row__n">{String(i + 1).padStart(2, "0")}</span>
            <span className="receipt-row__b">
              <span className="receipt-row__k">{r.k}</span>
              <span className="receipt-row__v">{r.em ? <em>{r.v}</em> : r.v}</span>
            </span>
          </div>
        ))}
      </div>
      <div className="receipt__foot">
        <div className="receipt__hash">RECONSTRUCTION ID · {hashMarks(s.marks)}</div>
        <div className="receipt__hash">{s.totalMarks} marks · same walk, same record, every time</div>
        {allDone && <div className="receipt__stamp">Defensible</div>}
      </div>
    </div>
  );
}

/* ---------- 07 INTEGRATION ---------- */
function Integration({ w }) {
  const s = window.useJourney();
  const m = s.marks.integration;
  return (
    <>
      <Reveal>
        <div style={{ marginTop: "var(--sp-7)" }}>
          <div className="section__eyebrow"><span>The single truth underneath</span><span className="dash" /></div>
          <div className="vision-line" style={{ maxWidth: "28ch" }}>{w.truth}</div>
        </div>
      </Reveal>

      <Reveal as="section" className="section">
        <SectionHead>Three ways to remember · the same insight, three times</SectionHead>
        <div className="images">
          {w.images.map((im, i) => (
            <div className="image-row" key={i}>
              <div className="image-row__h">{im.h}</div>
              <div className="image-row__t">{im.t}</div>
            </div>
          ))}
        </div>
      </Reveal>

      <Reveal as="section" className="section">
        <SectionHead>Close the loop</SectionHead>
        <TextMark label={w.prompt.label} placeholder={w.prompt.placeholder}
          value={m.note} onChange={(v) => s.setMark("integration", { note: v })} />
        <div className="identity">
          <div className="identity__eyebrow">The lens you carry out</div>
          <div className="identity__t">{w.identity}</div>
        </div>
      </Reveal>

      <Reveal as="section" className="section">
        <SectionHead>Your receipt · everything you gathered, in order</SectionHead>
        <Receipt />
        <div style={{ display: "flex", gap: "var(--sp-4)", marginTop: "var(--sp-5)", flexWrap: "wrap" }}>
          <button className="btn btn--ghost" onClick={() => window.print()}>
            <Icon name="print" size={16} /> Print the receipt
          </button>
          <button className="btn-text" onClick={() => s.setLedgerOpen(true)}>
            <Icon name="ledger" size={15} /><span className="u">Review the full ledger</span>
          </button>
        </div>
      </Reveal>
    </>
  );
}

/* ---------- dispatcher ---------- */
const STAGE_BODY = {
  listening: Listening, framing: Framing, envisioning: Envisioning,
  assumptions: Assumptions, transformation: Transformation, crux: Crux, integration: Integration,
};

function StageView() {
  const s = window.useJourney();
  const idx = s.view;
  const w = s.WPS[idx];
  const Body = STAGE_BODY[w.id];
  return (
    <main className="stage" key={w.id}>
      <StageShell w={w} idx={idx}>
        <Body w={w} />
      </StageShell>
    </main>
  );
}

Object.assign(window, { StageView, StageShell, Receipt, buildReceiptRows, hashMarks });
