/* Main app — calm narrative.
 * State machine: userTyping → forge1 → forge2 → progress → result(+ preview)
 * Switching tabs restarts. Replay button after done.
 */

const { useState, useEffect, useRef, useMemo } = React;

const PREVIEWS = {
  hotel:      window.HotelPreview,
  documents:  window.DocumentsPreview,
  hospital:   window.HospitalPreview,
  government: window.GovernmentPreview,
  finance:    window.FinancePreview,
  pharmacy:   window.PharmacyPreview,
  portal:     window.PortalPreview,
  workbook:   window.WorkbookPreview,
};

const CHAR_MS_USER  = 24;
const CHAR_MS_FORGE = 18;

// ─── Hook: drive the scene timeline ───────────────────────────────────────
function useSceneTimeline(scene, replayKey) {
  const [s, setS] = useState({
    phase: "userTyping",   // userTyping | userDone | forgeThinking | forge1 | forge2 | progress | result | done
    userIdx: 0,
    forge1Idx: 0,
    forge2Idx: 0,
    forge1Visible: false,
    forge2Visible: false,
    progressPhase: 0,       // 0..2 (reading / building / done)
    progressPct: 0,
    previewVisible: false,
    resultVisible: false,
  });

  useEffect(() => {
    setS({
      phase: "userTyping",
      userIdx: 0, forge1Idx: 0, forge2Idx: 0,
      forge1Visible: false, forge2Visible: false,
      progressPhase: 0, progressPct: 0,
      previewVisible: false, resultVisible: false,
    });

    const timers = [];
    const at = (ms, fn) => timers.push(setTimeout(fn, ms));

    let t = 350; // small initial breath
    // 1) Type user message
    for (let i = 1; i <= scene.user.length; i++) {
      at(t + i * CHAR_MS_USER, () => setS(p => ({ ...p, userIdx: i })));
    }
    t += scene.user.length * CHAR_MS_USER + 900;

    // 2) Forge thinking dots
    at(t, () => setS(p => ({ ...p, phase: "forgeThinking" })));
    t += 800;

    // 3) Show forge line 1 container + type it
    at(t, () => setS(p => ({ ...p, phase: "forge1", forge1Visible: true })));
    for (let i = 1; i <= scene.forge[0].length; i++) {
      at(t + i * CHAR_MS_FORGE, () => setS(p => ({ ...p, forge1Idx: i })));
    }
    t += scene.forge[0].length * CHAR_MS_FORGE + 550;

    // 4) Forge line 2
    at(t, () => setS(p => ({ ...p, phase: "forge2", forge2Visible: true })));
    for (let i = 1; i <= scene.forge[1].length; i++) {
      at(t + i * CHAR_MS_FORGE, () => setS(p => ({ ...p, forge2Idx: i })));
    }
    t += scene.forge[1].length * CHAR_MS_FORGE + 700;

    // 5) Progress phases
    at(t, () => setS(p => ({ ...p, phase: "progress", progressPhase: 0, progressPct: 0 })));
    // animate progress smoothly: tick every 60ms
    const totalProgressMs = scene.phases.reduce((a, b) => a + b.ms, 0);
    let elapsed = 0;
    const start = t;
    const tickInterval = 50;
    const totalTicks = Math.ceil(totalProgressMs / tickInterval);
    for (let i = 1; i <= totalTicks; i++) {
      at(start + i * tickInterval, () => {
        const ms = i * tickInterval;
        // compute phase
        let acc = 0; let ph = 0;
        for (let p = 0; p < scene.phases.length; p++) {
          if (ms <= acc + scene.phases[p].ms) { ph = p; break; }
          acc += scene.phases[p].ms;
        }
        if (ms >= totalProgressMs) ph = scene.phases.length - 1;
        const pct = Math.min(100, (ms / totalProgressMs) * 100);
        setS(p => ({ ...p, progressPhase: ph, progressPct: pct }));
      });
    }
    t += totalProgressMs;

    // 6) Preview fades in slightly before progress finishes
    at(t - 350, () => setS(p => ({ ...p, previewVisible: true })));

    // 7) Result line
    t += 400;
    at(t, () => setS(p => ({ ...p, phase: "result", resultVisible: true })));

    // 8) Mark done
    t += 200;
    at(t, () => setS(p => ({ ...p, phase: "done" })));

    return () => timers.forEach(clearTimeout);
  }, [scene.id, replayKey]);

  return s;
}

// ─── Atoms ────────────────────────────────────────────────────────────────
function TypingCursor() {
  return <span className="caret" />;
}

function ThinkingDots() {
  return (
    <span style={{ display: "inline-flex", alignItems: "center", height: 18 }}>
      <span className="dot" />
      <span className="dot" />
      <span className="dot" />
    </span>
  );
}

// ─── Layout ───────────────────────────────────────────────────────────────
function ForgeMark() {
  return (
    <svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
      <path d="M11 1.5 L20 6.5 L20 15.5 L11 20.5 L2 15.5 L2 6.5 Z" stroke="#d99350" strokeWidth="1.3" fill="none" />
      <path d="M11 6.5 L11 14" stroke="#d99350" strokeWidth="1.3" strokeLinecap="round" />
      <path d="M7.5 8.5 L14.5 8.5" stroke="#d99350" strokeWidth="1.3" strokeLinecap="round" />
    </svg>
  );
}

function Header({ scenes, currentId, onPick }) {
  return (
    <div style={{
      padding: "20px 32px 0",
      display: "flex", alignItems: "center", gap: 24,
      flexShrink: 0,
    }}>
      <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
        <ForgeMark />
        <span className="serif" style={{ fontSize: 19, letterSpacing: "-0.01em", color: "var(--ink)" }}>
          forge<span style={{ color: "var(--amber)" }}>ai</span>
        </span>
      </div>
      <div style={{ flex: 1 }} />
      <div style={{ display: "flex", gap: 2, flexWrap: "wrap", justifyContent: "flex-end" }}>
        {scenes.map(s => {
          const active = s.id === currentId;
          return (
            <button key={s.id} onClick={() => onPick(s.id)} style={{
              padding: "7px 12px",
              fontSize: 12.5,
              letterSpacing: "0.02em",
              color: active ? "#f4f1ea" : "#7e7b74",
              position: "relative",
              whiteSpace: "nowrap",
            }}>
              {s.tab}
              <span style={{
                position: "absolute",
                left: "50%", transform: "translateX(-50%)",
                bottom: 0,
                width: active ? 22 : 0,
                height: 1,
                background: "var(--amber)",
                transition: "width 0.3s cubic-bezier(0.2, 0.7, 0.2, 1)",
              }} />
            </button>
          );
        })}
      </div>
    </div>
  );
}

function ConversationPane({ scene, s, onReplay }) {
  const showUser     = s.userIdx > 0;
  const showThinking = s.phase === "forgeThinking";
  const showForge1   = s.forge1Visible;
  const showForge2   = s.forge2Visible;
  const showProgress = ["progress", "result", "done"].includes(s.phase);
  const showResult   = s.resultVisible;
  const userText = scene.user.slice(0, s.userIdx);
  const f1 = scene.forge[0].slice(0, s.forge1Idx);
  const f2 = scene.forge[1].slice(0, s.forge2Idx);

  const userTypingNow  = s.phase === "userTyping" && s.userIdx < scene.user.length;
  const forge1TypingNow = s.phase === "forge1" && s.forge1Idx < scene.forge[0].length;
  const forge2TypingNow = s.phase === "forge2" && s.forge2Idx < scene.forge[1].length;

  return (
    <div style={{
      width: "40%",
      minWidth: 380,
      padding: "32px 32px 24px 32px",
      display: "flex", flexDirection: "column",
      gap: 22,
      overflow: "auto",
      minHeight: 0,
    }}>
      {/* User */}
      {showUser && (
        <div>
          <div style={{
            fontSize: 11,
            letterSpacing: "0.16em", textTransform: "uppercase",
            color: "var(--ink-3)",
            marginBottom: 8,
          }}>You</div>
          <div style={{
            fontSize: 19,
            lineHeight: 1.42,
            color: "var(--ink)",
            fontWeight: 300,
            letterSpacing: "-0.005em",
            textWrap: "pretty",
          }}>
            {userText}
            {userTypingNow && <TypingCursor />}
          </div>
        </div>
      )}

      {/* Forge */}
      {(showThinking || showForge1) && (
        <div className="fade-up">
          <div style={{
            fontSize: 11,
            letterSpacing: "0.16em", textTransform: "uppercase",
            color: "var(--amber)",
            marginBottom: 8,
            display: "flex", alignItems: "center", gap: 8,
          }}>
            <ForgeMark />
            <span>ForgeAI</span>
          </div>

          {showThinking && !showForge1 && (
            <div style={{ paddingTop: 4 }}>
              <ThinkingDots />
            </div>
          )}

          {showForge1 && (
            <div style={{
              fontSize: 15.5,
              lineHeight: 1.5,
              color: "var(--ink-2)",
              fontWeight: 300,
              textWrap: "pretty",
            }}>
              <div>
                {f1}
                {forge1TypingNow && <TypingCursor />}
              </div>
              {showForge2 && (
                <div style={{ marginTop: 10, color: "var(--ink-3)" }}>
                  {f2}
                  {forge2TypingNow && <TypingCursor />}
                </div>
              )}
            </div>
          )}
        </div>
      )}

      {/* Progress */}
      {showProgress && (
        <div className="fade-up" style={{ marginTop: 4 }}>
          <div style={{
            display: "flex", justifyContent: "space-between",
            fontSize: 12, color: "var(--ink-3)",
            letterSpacing: "0.04em",
            marginBottom: 10,
          }}>
            <span>{scene.phases[s.progressPhase].label}</span>
            <span className="mono">{Math.round(s.progressPct)}%</span>
          </div>
          <div style={{ height: 2, background: "var(--bg-3)", borderRadius: 1, overflow: "hidden" }}>
            <div style={{
              height: "100%",
              width: s.progressPct + "%",
              background: "var(--amber)",
              transition: "width 0.18s linear",
              boxShadow: "0 0 8px rgba(217,147,80,0.4)",
            }} />
          </div>
        </div>
      )}

      {/* Result */}
      {showResult && (
        <div className="fade-up" style={{ marginTop: 4 }}>
          <div style={{
            fontSize: 11,
            letterSpacing: "0.16em", textTransform: "uppercase",
            color: "var(--ink-3)",
            marginBottom: 8,
          }}>Done</div>
          <div style={{
            fontSize: 14.5,
            lineHeight: 1.55,
            color: "var(--ink-2)",
            fontWeight: 300,
            textWrap: "pretty",
          }}>
            {scene.result}
          </div>

          {s.phase === "done" && (
            <button onClick={onReplay} className="fade-up" style={{
              marginTop: 22,
              padding: "8px 16px",
              fontSize: 12,
              letterSpacing: "0.04em",
              color: "var(--ink-2)",
              border: "1px solid var(--line-2)",
              borderRadius: 999,
              display: "inline-flex", alignItems: "center", gap: 8,
              transition: "all 0.2s ease",
            }}
            onMouseEnter={e => { e.currentTarget.style.borderColor = "var(--amber-dim)"; e.currentTarget.style.color = "var(--amber-2)"; }}
            onMouseLeave={e => { e.currentTarget.style.borderColor = "var(--line-2)"; e.currentTarget.style.color = "var(--ink-2)"; }}
            >
              <svg width="11" height="11" viewBox="0 0 11 11" fill="none">
                <path d="M2 5.5 a3.5 3.5 0 1 0 1 -2.5" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" fill="none" />
                <path d="M3 1 L3 3.5 L5.5 3.5" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" fill="none" />
              </svg>
              Replay
            </button>
          )}
        </div>
      )}
    </div>
  );
}

function PreviewPane({ scene, visible }) {
  const Comp = PREVIEWS[scene.preview];
  return (
    <div style={{
      flex: 1,
      padding: "32px 32px 32px 16px",
      display: "flex", alignItems: "center", justifyContent: "center",
      overflow: "auto",
      minWidth: 0,
    }}>
      <div style={{
        width: "100%",
        maxWidth: 780,
        opacity: visible ? 1 : 0,
        transform: visible ? "translateY(0)" : "translateY(20px)",
        transition: "opacity 0.7s cubic-bezier(0.2,0.7,0.2,1), transform 0.7s cubic-bezier(0.2,0.7,0.2,1)",
      }}>
        {visible && Comp && <Comp />}
        {!visible && (
          <div style={{
            height: 460,
            display: "flex", alignItems: "center", justifyContent: "center",
            opacity: 0.4,
          }}>
            {/* subtle placeholder shimmer */}
          </div>
        )}
      </div>
    </div>
  );
}

function App() {
  const scenes = window.SCENES;
  const [currentId, setCurrentId] = useState("hotel");
  const [replayKey, setReplayKey] = useState(0);
  const scene = scenes.find(s => s.id === currentId);

  const s = useSceneTimeline(scene, replayKey);

  const pick = (id) => {
    if (id === currentId) {
      setReplayKey(k => k + 1);
    } else {
      setCurrentId(id);
      setReplayKey(k => k + 1);
    }
  };

  return (
    <div style={{ height: "100%", width: "100%", display: "flex", flexDirection: "column" }}>
      <Header scenes={scenes} currentId={currentId} onPick={pick} />
      <div style={{ flex: 1, display: "flex", minHeight: 0 }}>
        <ConversationPane scene={scene} s={s} onReplay={() => setReplayKey(k => k + 1)} />
        <PreviewPane scene={scene} visible={s.previewVisible} />
      </div>

      {/* Subtle footer */}
      <div style={{
        padding: "10px 32px 14px",
        display: "flex", justifyContent: "space-between", alignItems: "center",
        fontSize: 11,
        color: "var(--ink-4)",
        letterSpacing: "0.04em",
        flexShrink: 0,
      }}>
        <span>forgeai · a context-grounded execution agent</span>
        <span>{s.phase === "done" ? "ready" : s.phase === "progress" ? scene.phases[s.progressPhase].label : "in progress"}</span>
      </div>
    </div>
  );
}

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