/* global React, window, Contours, Artifact, LocationHead, LayerTag, NextButton */
const { useState: useStateA, useMemo: useMemoA } = React;

/* =========================================================
   HOME — orientation, not navigation. The atlas overview.
   ========================================================= */
const HOME_NODES = [
  { x: 8,  y: 74 }, { x: 22, y: 52 }, { x: 35, y: 64 }, { x: 49, y: 40 },
  { x: 62, y: 58 }, { x: 76, y: 34 }, { x: 90, y: 50 },
];
function HomeMap({ locations, homepageStyle }) {
  const route = `M ${HOME_NODES[0].x} ${HOME_NODES[0].y} ` +
    HOME_NODES.slice(1).map((n, i) => {
      const p = HOME_NODES[i];
      const mx = (p.x + n.x) / 2;
      return `Q ${mx} ${p.y} ${n.x} ${n.y}`;
    }).join(" ");
  return (
    <div className="home-map" aria-hidden="true">
      <svg viewBox="0 0 100 90" preserveAspectRatio="xMidYMid meet">
        {homepageStyle !== "spare" && (
          <g stroke="var(--fog)" strokeWidth="0.25" fill="none" vectorEffect="non-scaling-stroke">
            {[0,1,2,3,4].map(i => (
              <ellipse key={i} cx="50" cy="48" rx={14 + i*11} ry={9 + i*7.5} />
            ))}
            {[0,1,2].map(i => (
              <ellipse key={"b"+i} cx="76" cy="34" rx={5 + i*7} ry={4 + i*5} />
            ))}
          </g>
        )}
        <path d={route} fill="none" stroke="var(--ash)" strokeWidth="0.4"
          strokeDasharray="1.4 2.4" vectorEffect="non-scaling-stroke" />
        {HOME_NODES.map((n, i) => (
          <g key={i}>
            <rect x={n.x - 1.1} y={n.y - 1.1} width="2.2" height="2.2"
              fill={i === 0 ? "var(--signal)" : "var(--paper)"}
              stroke={i === 0 ? "var(--signal)" : "var(--ink)"} strokeWidth="0.35"
              vectorEffect="non-scaling-stroke" />
            <text x={n.x} y={n.y - 2.6} textAnchor="middle"
              fontFamily="var(--font-mono)" fontSize="1.7" fill="var(--ash)"
              letterSpacing="0.05">{locations[i].roman}</text>
          </g>
        ))}
      </svg>
    </div>
  );
}

function Home({ locations, onBegin, homepageStyle, headline }) {
  return (
    <section className="stage home-stage" data-screen-label="Home · Orientation">
      <Contours density="off" />
      <div className="home-grid">
        <div className="home-copy fade-rise">
          <div className="home-eyebrow">
            <span className="session-dot" />Demand Discovery · field expedition
          </div>
          <h1 className={"home-title " + (homepageStyle === "stark" ? "is-stark" : "")}>
            {headline === "alt"
              ? <>We do not yet<br/>know what<br/><span className="serif-i">matters.</span></>
              : <>Every meaningful<br/>decision begins<br/>as a <span className="serif-i">mystery.</span></>}
          </h1>
          <p className="home-sub">
            We are here to uncover what matters — not to defend what we already believe.
            This is a shared field notebook for collective sense-making.
          </p>
          <div className="home-actions">
            <button className="btn btn--primary btn--lg" onClick={onBegin}>
              Begin the investigation <span className="arrow">→</span>
            </button>
            <span className="coord">7 fields · evidence accumulates · the destination is unknown</span>
          </div>
        </div>
        <div className="home-mapwrap">
          <HomeMap locations={locations} homepageStyle={homepageStyle} />
          <div className="home-legend">
            {locations.map((l) => (
              <div key={l.id} className="home-legend__row">
                <span className="rm">{l.roman}</span>
                <span className="nm serif">{l.name.replace("The ", "")}</span>
                <span className="ph">{l.phase}</span>
              </div>
            ))}
          </div>
        </div>
      </div>
    </section>
  );
}

/* =========================================================
   OBSERVATORY — Listening. Field notes drift; pick up, mark
   a phrase, place on the evidence wall.
   ========================================================= */
function Observatory({ loc, data, carto, onNext, selected, setSelected, highlighted, setHighlighted }) {
  const placedCount = Object.values(selected).filter(Boolean).length;
  const toggle = (id) => setSelected((s) => ({ ...s, [id]: !s[id] }));
  const hl = (id) => setHighlighted((h) => ({ ...h, [id]: !h[id] }));
  return (
    <section className="stage" data-screen-label="I · The Observatory">
      <Contours density={carto} seed={11} />
      <div className="stage__inner">
        <LocationHead loc={loc} />

        <div className="obs-prompts fade-rise-2">
          {data.prompts.map((p, i) => <span key={i} className="obs-prompt">{p}</span>)}
        </div>

        <LayerTag n="01 · Observation">What are we hearing</LayerTag>
        <p className="measure muted fade-rise" style={{ marginBottom: "var(--sp-6)" }}>{data.intro}</p>

        <div className="grid grid-3 obs-wall fade-rise-2">
          {data.notes.map((n) => (
            <Artifact key={n.id} note={n}
              selected={!!selected[n.id]} onToggle={() => toggle(n.id)}
              highlighted={!!highlighted[n.id]} onHighlight={() => hl(n.id)} />
          ))}
        </div>

        <div className="obs-foot">
          <div className="layer-tag" style={{ marginTop: "var(--sp-8)" }}>
            <span className="n">02 · Reflection</span><span>What we heard you say</span>
          </div>
          <p className="pull serif" style={{ fontSize: 24, lineHeight: 1.3 }}>{data.reflect}</p>
          <div className="obs-counter">
            <span className="coord">
              {placedCount === 0
                ? "Pick up the notes that feel important. Click a phrase to mark it."
                : `${placedCount} note${placedCount > 1 ? "s" : ""} on the evidence wall · they will travel with us.`}
            </span>
            <NextButton label="Carry these to the table" onClick={onNext} />
          </div>
        </div>
      </div>
    </section>
  );
}

/* =========================================================
   CARTOGRAPHER'S TABLE — Framing. Local pairwise decisions;
   groups and the challenge emerge.
   ========================================================= */
function Cartographer({ loc, data, carto, onNext }) {
  const [i, setI] = useStateA(0);
  const [decisions, setDecisions] = useStateA({});
  const [revealed, setRevealed] = useStateA(false);
  const pair = data.pairs[i];
  const decide = (val) => {
    setDecisions((d) => ({ ...d, [pair.id]: val }));
  };
  const decided = decisions[pair.id] !== undefined;
  const allDone = data.pairs.every((p) => decisions[p.id] !== undefined);

  return (
    <section className="stage" data-screen-label="II · The Cartographer's Table">
      <Contours density={carto} seed={23} />
      <div className="stage__inner">
        <LocationHead loc={loc} />
        <LayerTag n="01 · Observation">{data.intro}</LayerTag>

        {!revealed ? (
          <div className="carto-compare fade-rise-2">
            <div className="carto-progress coord">
              Comparison {String(i + 1).padStart(2, "0")} / {String(data.pairs.length).padStart(2, "0")}
            </div>
            <div className="carto-pair">
              <div className="carto-obj">
                <div className="artifact__meta"><span className="src">{pair.a.src}</span></div>
                <p className="carto-obj__t serif">{pair.a.text}</p>
              </div>
              <div className="carto-vs">
                <span className="carto-vs__line" />
                <span className="carto-vs__q">belong<br/>together?</span>
                <span className="carto-vs__line" />
              </div>
              <div className="carto-obj">
                <div className="artifact__meta"><span className="src">{pair.b.src}</span></div>
                <p className="carto-obj__t serif">{pair.b.text}</p>
              </div>
            </div>

            {decided ? (
              <div className="carto-result fade-rise">
                <div className="carto-verdict">
                  <span className={"carto-badge " + (decisions[pair.id] === pair.belong ? "agree" : "differ")}>
                    {decisions[pair.id] ? "Grouped together" : "Kept apart"}
                  </span>
                  <span className="coord">
                    {decisions[pair.id] === pair.belong ? "Consistent with the session." : "A defensible reading — the session leaned the other way."}
                  </span>
                </div>
                <p className="measure">{pair.because}</p>
                <div className="row" style={{ marginTop: "var(--sp-5)", justifyContent: "space-between" }}>
                  <span className="coord">{i + 1} of {data.pairs.length} decided</span>
                  {i < data.pairs.length - 1
                    ? <NextButton label="Next comparison" onClick={() => setI(i + 1)} variant="primary" />
                    : <NextButton label="See the challenge that emerged" onClick={() => setRevealed(true)} variant="signal" />}
                </div>
              </div>
            ) : (
              <div className="carto-actions">
                <button className="btn btn--lg" onClick={() => decide(true)}>Belong together</button>
                <button className="btn btn--lg" onClick={() => decide(false)}>Keep apart</button>
              </div>
            )}
          </div>
        ) : (
          <div className="carto-emerge fade-rise">
            <div className="layer-tag"><span className="n">02 · Reflection</span><span>The problem in four statements</span></div>
            <div className="grid grid-2">
              {data.problems.map((p) => (
                <div key={p.n} className={"prob" + (p.visible ? "" : " prob--deep")}>
                  <div className="prob__head">
                    <span className="prob__n">{p.n}</span>
                    <span className="prob__tag">{p.visible ? "STATED" : "BENEATH"}</span>
                  </div>
                  <h3 className="prob__t serif">{p.title}</h3>
                  <p className="body-s muted">{p.text}</p>
                </div>
              ))}
            </div>

            <div className="layer-tag" style={{ marginTop: "var(--sp-8)" }}>
              <span className="n">03 · Synthesis</span><span>The challenge is discovered, not declared</span>
            </div>
            <div className="carto-challenges">
              <div className="challenge">
                <span className="challenge__lbl">THE VISIBLE CHALLENGE</span>
                <p className="challenge__t serif">{data.visibleChallenge}</p>
              </div>
              <div className="challenge challenge--deep">
                <span className="challenge__lbl signal-word">THE DEEPER CHALLENGE</span>
                <p className="challenge__t serif">{data.deeperChallenge}</p>
              </div>
            </div>
            <div className="row" style={{ marginTop: "var(--sp-7)", justifyContent: "flex-end" }}>
              <NextButton label="Look toward the horizon" onClick={onNext} />
            </div>
          </div>
        )}
      </div>
    </section>
  );
}

/* =========================================================
   HORIZON ROOM — Envisioning. Dark. Distant futures expand.
   ========================================================= */
function Horizon({ loc, data, onNext }) {
  const [open, setOpen] = useStateA(null);
  const [visited, setVisited] = useStateA({});
  const choose = (id) => {
    setOpen(open === id ? null : id);
    setVisited((v) => ({ ...v, [id]: true }));
  };
  return (
    <section className="stage" data-screen-label="III · The Horizon Room">
      <Contours density="faint" seed={31} />
      <div className="stage__inner">
        <LocationHead loc={loc} />
        <LayerTag n="01 · Observation">{data.intro}</LayerTag>

        <div className="horizon-line fade-rise-2">
          {data.futures.map((f) => (
            <button key={f.id}
              className={"future" + (open === f.id ? " open" : "") + (visited[f.id] ? " seen" : "")}
              onClick={() => choose(f.id)}>
              <span className="future__star" />
              <span className="future__bearing">{f.bearing}</span>
              <span className="future__label serif">{f.label}</span>
              {f.recommended && <span className="future__rec">RECOMMENDED PATH</span>}
              <span className="future__line">{f.line}</span>
            </button>
          ))}
        </div>

        {open && (() => {
          const f = data.futures.find((x) => x.id === open);
          return (
            <div className="horizon-detail fade-rise">
              <div className="layer-tag"><span className="n">02 · Reflection</span><span>If this future became true…</span></div>
              <div className="horizon-detail__grid">
                <div>
                  <h3 className="serif" style={{ fontSize: 34, marginBottom: "var(--sp-3)" }}>{f.label}</h3>
                  <p className="muted measure">{f.verdict}</p>
                </div>
                <ul className="consq">
                  {f.consequences.map((c, i) => <li key={i}>{c}</li>)}
                </ul>
              </div>
            </div>
          );
        })()}

        <div className="horizon-foot">
          <div className="layer-tag" style={{ marginTop: "var(--sp-8)" }}>
            <span className="n">03 · Synthesis</span><span>The crisp vision</span>
          </div>
          <p className="pull serif" style={{ fontSize: 28, lineHeight: 1.25, borderColor: "var(--signal)" }}>
            {data.vision}
          </p>
          <div className="row" style={{ marginTop: "var(--sp-6)", justifyContent: "space-between" }}>
            <span className="coord">{Object.keys(visited).length} / {data.futures.length} futures explored</span>
            <NextButton label="Descend to the archive" onClick={onNext} />
          </div>
        </div>
      </div>
    </section>
  );
}

Object.assign(window, { Home, Observatory, Cartographer, Horizon });
