/* global React, ReactDOM, window, useTweaks, TweaksPanel, TweakSection, TweakRadio, TweakToggle,
   Trail, FrictionGate, Home, Observatory, Cartographer, Horizon, Iceberg, River, MountainPass, Constellation */
const { useState, useEffect } = React;
const D = window.ATLAS_DATA;

const FACILITATOR = {
  observatory:   { meaning: "Attention before interpretation.", note: "Let the room read the notes aloud. Resist grouping. ~12 min." },
  cartographer:  { meaning: "The challenge is discovered, not declared.", note: "Force local yes/no calls. Don’t build the giant affinity wall. ~15 min." },
  horizon:       { meaning: "Exploration before commitment.", note: "Hold all three futures open before naming a favorite. ~10 min." },
  iceberg:       { meaning: "Surface hidden beliefs.", note: "Pull the most load-bearing assumption first. ~12 min." },
  river:         { meaning: "Understand movement, not outcomes.", note: "ACTIVATE LIVE — this step and the Pass may run in-session." },
  pass:          { meaning: "Focus emerges, not consensus.", note: "ACTIVATE LIVE — compare cruxes one at a time. ~15 min." },
  constellation: { meaning: "Understanding becomes visible.", note: "Nothing new is added here. Only relationships. ~8 min." },
};

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "treatment": "cartographic",
  "homeHeadline": "mystery",
  "homeTitle": "serif",
  "trailLabels": "phase",
  "artifactFill": "outlined",
  "roomMode": "atlas"
}/*EDITMODE-END*/;

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [view, setView] = useState(-1);          // -1 home, 0..6 locations, 7 done
  const [maxReached, setMaxReached] = useState(-1);
  const [pendingGate, setPendingGate] = useState(null);
  const [gateChoices, setGateChoices] = useState({});
  const [facil, setFacil] = useState(false);

  // Observatory persistent state (evidence travels with you)
  const [selected, setSelected] = useState({});
  const [highlighted, setHighlighted] = useState({});

  const locations = D.LOCATIONS;

  // ---- restore session / deep-link (#go=N) ----
  useEffect(() => {
    const m = (window.location.hash.match(/go=(\d+)/) || [])[1];
    if (m !== undefined) {
      const n = Math.max(0, Math.min(locations.length - 1, parseInt(m, 10)));
      setView(n); setMaxReached((x) => Math.max(x, n)); return;
    }
    try {
      const saved = JSON.parse(localStorage.getItem("atlas-session") || "null");
      if (saved && typeof saved.max === "number") {
        setMaxReached(saved.max);
        setGateChoices(saved.gates || {});
        setSelected(saved.selected || {});
        if (typeof saved.view === "number" && saved.view >= 0) setView(saved.view);
      }
    } catch (e) { /* ignore */ }
  }, []);
  useEffect(() => {
    try { localStorage.setItem("atlas-session", JSON.stringify({ view, max: maxReached, gates: gateChoices, selected })); }
    catch (e) { /* ignore */ }
  }, [view, maxReached, gateChoices, selected]);

  useEffect(() => { window.scrollTo(0, 0); }, [view, pendingGate]);

  const enter = (index) => {
    setView(index);
    setMaxReached((m) => Math.max(m, index));
  };
  const goTo = (index) => {
    if (index < 0) { setView(-1); return; }
    const loc = locations[index];
    const gate = D.GATES[loc.id];
    if (gate && gateChoices[loc.id] === undefined) { setPendingGate(index); return; }
    enter(index);
  };
  const resolveGate = (choice) => {
    const index = pendingGate;
    const loc = locations[index];
    setGateChoices((g) => ({ ...g, [loc.id]: choice }));
    setPendingGate(null);
    enter(index);
  };
  // Trail jump: free navigation for facilitators — enters directly, bypassing gates.
  const jumpTo = (index) => {
    if (index < 0) { setView(-1); return; }
    setPendingGate(null);
    enter(index);
  };

  const carto = t.treatment === "cartographic" ? "present" : (t.treatment === "editorial" ? "faint" : "off");
  const loc = view >= 0 && view < locations.length ? locations[view] : null;
  const forcedDark = t.roomMode === "alldark";
  const forcedLight = t.roomMode === "alllight";
  const isDark = forcedDark || (!forcedLight && loc && loc.dark);

  const rootClass = [
    "app",
    isDark ? "room-dark" : "",
    t.artifactFill === "filled" ? "art-filled" : "",
    t.trailLabels === "roman" ? "trail-roman" : "",
  ].filter(Boolean).join(" ");

  // ---- render current stage ----
  let stage = null;
  if (view === -1) {
    stage = <Home locations={locations} onBegin={() => goTo(0)}
      homepageStyle={t.homeTitle === "stark" ? "stark" : "serif"}
      headline={t.homeHeadline === "unknown" ? "alt" : "default"} />;
  } else if (view === 7) {
    stage = <DoneScreen onReopen={() => { setView(6); }} onRestart={restart} />;
  } else if (loc) {
    const common = { loc, carto, onNext: () => goTo(view + 1) };
    switch (loc.id) {
      case "observatory":  stage = <Observatory {...common} data={D.LISTENING} selected={selected} setSelected={setSelected} highlighted={highlighted} setHighlighted={setHighlighted} />; break;
      case "cartographer": stage = <Cartographer {...common} data={D.FRAMING} />; break;
      case "horizon":      stage = <Horizon {...common} data={D.ENVISIONING} />; break;
      case "iceberg":      stage = <Iceberg {...common} data={D.ASSUMPTIONS} />; break;
      case "river":        stage = <River {...common} data={D.TRANSFORMATION} />; break;
      case "pass":         stage = <MountainPass {...common} data={D.CRUX} />; break;
      case "constellation":stage = <Constellation loc={loc} data={D.INTEGRATION} onFinish={() => setView(7)} onRestart={restart} />; break;
      default: stage = null;
    }
  }

  function restart() { setView(-1); }

  const homTitleForStark = t.homeTitle; // referenced to satisfy lint

  return (
    <div className={rootClass}>
      <header className="masthead">
        <div className="masthead__wordmark">DARK HORSE WORKS</div>
        <div className="masthead__session">
          <span><span className="session-dot" />Demand Discovery</span>
          <span className="hide-sm">Client&nbsp; <b>ImmunoShield Therapeutics</b></span>
          <span className="hide-sm">Session&nbsp; <b>01</b></span>
          <button className="masthead__btn" onClick={() => setFacil((f) => !f)} aria-pressed={facil}>
            {facil ? "● Facilitator" : "○ Facilitator"}
          </button>
          <a className="masthead__btn" href="ddp/index.html" title="The 8-step DDP workflow">DDP workflow ↗</a>
        </div>
      </header>

      {facil && loc && (
        <div className="facilband">
          <span className="facilband__tag">FACILITATOR</span>
          <span className="facilband__meaning serif-i">{FACILITATOR[loc.id]?.meaning}</span>
          <span className="facilband__note">{FACILITATOR[loc.id]?.note}</span>
        </div>
      )}

      <main>{stage}</main>

      {view >= 0 && view < locations.length && (
        <Trail locations={locations} currentIndex={view} maxReached={maxReached} onJump={jumpTo} />
      )}

      {pendingGate !== null && (
        <FrictionGate gate={D.GATES[locations[pendingGate].id]} onResolve={resolveGate} />
      )}

      <TweaksPanel title="Tweaks">
        <TweakSection label="Visual treatment" />
        <TweakRadio label="Atlas linework" value={t.treatment}
          options={["editorial", "cartographic", "off"]}
          onChange={(v) => setTweak("treatment", v)} />
        <TweakRadio label="Rooms (light / dark)" value={t.roomMode}
          options={["atlas", "alllight", "alldark"]}
          onChange={(v) => setTweak("roomMode", v)} />

        <TweakSection label="Homepage" />
        <TweakRadio label="Headline" value={t.homeHeadline}
          options={["mystery", "unknown"]}
          onChange={(v) => setTweak("homeHeadline", v)} />
        <TweakRadio label="Title type" value={t.homeTitle}
          options={["serif", "stark"]}
          onChange={(v) => setTweak("homeTitle", v)} />

        <TweakSection label="Trail & evidence" />
        <TweakRadio label="Trail labels" value={t.trailLabels}
          options={["phase", "roman"]}
          onChange={(v) => setTweak("trailLabels", v)} />
        <TweakRadio label="Artifact fill" value={t.artifactFill}
          options={["outlined", "filled"]}
          onChange={(v) => setTweak("artifactFill", v)} />
      </TweaksPanel>
    </div>
  );
}

function DoneScreen({ onReopen, onRestart }) {
  return (
    <section className="stage done-stage" data-screen-label="Closing">
      <div className="stage__inner done-inner fade-rise">
        <div className="loc-head__index"><span className="signal">✓</span><span>EXPEDITION COMPLETE</span></div>
        <h1 className="serif" style={{ fontSize: "clamp(40px,6vw,76px)", lineHeight: 0.98, margin: "0 0 24px" }}>
          You did not complete a workshop.<br/>You ran an <span className="serif-i">investigation.</span>
        </h1>
        <p className="measure muted" style={{ fontSize: 18 }}>
          You followed evidence. You changed your mind. You found something you could not see at the trailhead —
          that ImmunoShield’s crux is not better science, but proving a partner will move.
        </p>
        <div className="row" style={{ marginTop: 40 }}>
          <button className="btn btn--lg" onClick={onRestart}>Return to the atlas</button>
          <button className="btn btn--primary btn--lg" onClick={onReopen}>Reopen the constellation →</button>
        </div>
      </div>
    </section>
  );
}

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