/* ============================================================
   shell.jsx — app shell, click-to-advance navigation
   No top bar, no logo, no persistent button.
   ============================================================ */
const AP = (function () {
  /* ---- 全局叙事顺序（唯一事实来源）----
     各 act 文件各自 push 屏幕，最终线性顺序在这里按 id 显式排定，
     以后调顺序只改这一处。未列入 ORDER 的屏按原 push 顺序补在末尾，避免漏屏。
     新骨架：投资人三痛点 → 引擎收口 → 多角色 → 市场 → 团队 → 怎么发现 → 怎么做 → 融资 */
  const ORDER = [
    "act1-flow", "act1-alert",          // 投资人三痛点（调研 / 约会 / 预警）
    "act1-engine",                       // 引擎收口：同一台引擎
    "roles",                             // 多角色：投资人只是其一
    "act2-market",                       // 市场有多大
    "team",                              // 为什么是我们
    "act2-paradigm", "act2-whynow",      // 我们怎么发现的（范式转移 + 为什么是现在）
    "act3-nosession", "why-2",           // 我们准备怎么做（硬核，why 交织）
    "act3-route", "why-3",
    "act3-runner", "why-4",
    "act3-eval",
    "act3-ask",                          // 融资
  ];
  const raw = window.AP_SCREENS || [];
  const byId = new Map(raw.map((s) => [s.id, s]));
  const ordered = ORDER.map((id) => byId.get(id)).filter(Boolean);
  const seen = new Set(ORDER);
  const screens = [...ordered, ...raw.filter((s) => !seen.has(s.id))];

  /* ---- intro cover (title only, no chrome, no logo) ---- */
  function Intro({ active, bus }) {
    useEffect(() => { bus.setReady(true); bus.setHint(null); }, []);
    return (
      <div className="intro">
        <h1 className="intro-title fade-up" style={{ animationDelay: ".18s" }}>
          只说任务，AgentPilot 负责找到最合适的完成路径。
        </h1>
        <p className="intro-sub fade-up" style={{ animationDelay: ".34s" }}>
          让普通人也用得上、用得起原本只属于极客的 agent 能力
        </p>
      </div>
    );
  }

  const ALL = [
    { id: "intro", chapter: "开始", Comp: Intro, cover: true },
    ...screens,
  ];

  function App() {
    const [step, setStep] = useState(() => {
      const v = parseInt(localStorage.getItem("ap_step") || "0", 10);
      return isNaN(v) ? 0 : Math.min(v, ALL.length - 1);
    });
    const [ready, setReady] = useState(false);
    const [hint, setHint] = useState(null);
    const [maxSeen, setMaxSeen] = useState(step);
    const [leaving, setLeaving] = useState(null);   // {step, dir} of the outgoing screen
    /* 进入屏的方向类，随导航固化、不随 leaving 的 560ms 生命周期回收。
       若用 leaving.dir 当方向类，back 类会在 560ms 后被收掉、className 回到 fwd，
       从而给屏幕“补”一次迟到的 screenEnter 入场动画 → 返回时仍会模糊抖动。 */
    const [enterDir, setEnterDir] = useState("fwd");
    const prevStepRef = useRef(step);
    /* 当前屏注册的「逐拍控制器」：屏内动画分多拍，方向键逐拍推进、点击自动播完。
       仅 active 屏会注册（leaving 屏用 noopBus）；屏切换时旧屏卸载清空、新屏挂载注册。 */
    const stepperRef = useRef(null);

    const debug = useDebugMode();
    const devOn = useDevUnlocked();
    const cur = ALL[step];

    /* 开发者总开关的唤出：网址 ?dev=1 / ?dev=0，或依次敲 d-e-v。
       默认锁住时把可能残留的调试态强制关掉，确保给投资人看的版本干净。 */
    useEffect(() => {
      try {
        const q = new URLSearchParams(window.location.search).get("dev");
        if (q === "1") setDevUnlocked(true);
        else if (q === "0") setDevUnlocked(false);
        else if (!devUnlocked()) setDebugMode(false);
      } catch (e) {}
    }, []);
    useEffect(() => {
      let buf = "";
      const onKey = (e) => {
        if (e.metaKey || e.ctrlKey || e.altKey) return;
        if (e.target && /^(INPUT|TEXTAREA)$/.test(e.target.tagName)) return;
        buf = (buf + e.key.toLowerCase()).slice(-3);
        if (buf === "dev") { setDevUnlocked(!devUnlocked()); buf = ""; }
      };
      window.addEventListener("keydown", onKey);
      return () => window.removeEventListener("keydown", onKey);
    }, []);
    /* 进屏方向（在 effect 更新 prevStepRef 之前于 render 期算出）：
       倒着进来(back)时该屏直接呈现末态，方向键左可继续逐拍回退；正着进来(fwd)则停在起始态。 */
    const entryDir = step < prevStepRef.current ? "back" : "fwd";

    useEffect(() => {
      localStorage.setItem("ap_step", String(step));
      setMaxSeen((m) => Math.max(m, step));
      document.body.dataset.chapter = cur.chapter || "体验";
      if (prevStepRef.current !== step) {
        const dir = step > prevStepRef.current ? "fwd" : "back";
        setLeaving({ step: prevStepRef.current, dir });
        setEnterDir(dir);
        prevStepRef.current = step;
        const t = setTimeout(() => setLeaving(null), 560);
        return () => clearTimeout(t);
      }
    }, [step]);

    const noopBus = { setReady() {}, setHint() {}, goNext() {}, goPrev() {}, registerStepper() {} };

    const isLast = step === ALL.length - 1;
    const isFirst = step === 0;

    const goNext = useCallback(() => {
      setStep((s) => Math.min(s + 1, ALL.length - 1));
      setReady(false); setHint(null);
    }, []);
    const goPrev = useCallback(() => {
      setStep((s) => Math.max(s - 1, 0));
      setReady(false); setHint(null);
    }, []);
    const goTo = useCallback((i) => {
      if (i >= 0 && i < ALL.length && (debug || i <= maxSeen)) { setStep(i); setReady(false); setHint(null); }
    }, [maxSeen, debug]);

    /* keyboard — 方向键「逐拍」推进屏内动画，拍走完才翻到下/上一屏；空格＝点击（自动播完/翻屏） */
    const tapAdvance = useCallback(() => {
      const s = stepperRef.current;
      if (s) { if (s.tap()) return; if (!isLast) goNext(); return; }
      if (ready && !isLast) goNext();   // 无屏内动画的静态屏
    }, [ready, isLast, goNext]);

    useEffect(() => {
      const onKey = (e) => {
        if (e.key === "d" || e.key === "D") { if (devOn && !e.metaKey && !e.ctrlKey && !e.altKey) setDebugMode(localStorage.getItem("ap_debug") !== "1"); return; }
        if (e.key === "ArrowRight" || e.key === "PageDown") {
          e.preventDefault();
          const s = stepperRef.current;
          if (s && s.next()) return;   // 推进了一拍
          goNext();                     // 已是末拍 → 下一屏
        } else if (e.key === "ArrowLeft" || e.key === "PageUp") {
          e.preventDefault();
          const s = stepperRef.current;
          if (s && s.prev()) return;   // 回退了一拍
          goPrev();                     // 已是首拍 → 上一屏
        } else if (e.key === " ") { e.preventDefault(); tapAdvance(); }
      };
      window.addEventListener("keydown", onKey);
      return () => window.removeEventListener("keydown", onKey);
    }, [ready, step, tapAdvance, devOn]);

    const bus = {
      setReady: (r) => setReady(r),
      setHint: (h) => setHint(h),
      goNext, goPrev,
      registerStepper: (s) => { stepperRef.current = s; },
      entryDir,
    };

    /* 点击任意处：屏内动画没播完→自动播完；已播完→翻到下一屏（避开交互控件） */
    const onStageClick = (e) => {
      if (e.target.closest("button, a, input, .no-advance")) return;
      tapAdvance();
    };

    return (
      <div className="app">
        <div className="stage" onClick={onStageClick}>
          {leaving && (
            <div key={"leave-" + leaving.step} className={"screen leaving " + leaving.dir}>
              {(() => { const L = ALL[leaving.step]; return <L.Comp active={false} bus={noopBus} />; })()}
            </div>
          )}
          <div key={step} className={"screen enter " + enterDir}>
            <cur.Comp active={true} bus={bus} />
          </div>
        </div>

        {/* back affordance */}
        {!isFirst && (
          <button className="back-aff no-advance" onClick={goPrev} aria-label="上一步"><Icon name="ChevronLeft" size={22} /></button>
        )}

        {/* global debug-mode toggle — only in dev mode (unlock: ?dev=1 or type d-e-v) */}
        {devOn && (
          <button className={"dbg-toggle no-advance" + (debug ? " on" : "")}
                  onClick={(e) => { e.stopPropagation(); setDebugMode(!debug); }}
                  title="切换调试模式（快捷键 D）">
            {debug ? "✕ 退出调试" : "🔧 调试"}
          </button>
        )}

        {/* in-page copy editor — dev only; saves straight back to source via serve.py */}
        {devOn && <CopyEditor />}

        {/* progress dots — minimal, no labels, no logo */}
        {!cur.cover && (
          <div className="progress no-advance">
            {ALL.map((s, i) => (
              <button key={i}
                className={"pdot" + (i === step ? " on" : "") + (i < step ? " seen" : "")}
                disabled={!debug && i > maxSeen}
                onClick={(e) => { e.stopPropagation(); goTo(i); }} />
            ))}
          </div>
        )}

        {/* continue affordance — only when the screen is settled */}
        <div className={"continue-aff" + (ready && !isLast ? " show" : "")}>
          {hint && <span className="ca-hint">{hint}</span>}
          {!isLast && <span className="ca-tap">{isFirst ? "轻点任意处开始" : "轻点屏幕任意处继续"} ›</span>}
          {isLast && ready && (
            <button className="ca-restart no-advance" onClick={() => goTo(0)}><Icon name="RotateCcw" size={14} /> 重新体验</button>
          )}
        </div>
      </div>
    );
  }

  return { App };
})();

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