// Corridor — "Simulate a runaway agent" (the centerpiece interaction).
// Purely client-side against synthetic data; never writes real state.
// A synthetic agent fires a burst of calls, spend races toward the
// $25/day budget cap, then the budget policy DENIES the rest before
// any of it executes. Honors prefers-reduced-motion (jumps to the
// resolved end-state). Reset replays.
const NS_sim = window.CorridorDesignSystem_8d69e0;
const D_sim = window.CorridorDemo;

function RunawaySimulation({ onStateChange }) {
  const cfg = D_sim.sim;
  const { Button, Badge } = NS_sim;
  const [phase, setPhase] = React.useState("idle"); // idle | running | done
  const [fired, setFired] = React.useState([]);     // [{i, kind, spend}]
  const timers = React.useRef([]);
  const listRef = React.useRef(null);

  const spend = fired.length ? fired[fired.length - 1].spend : 0;
  const capturedCount = fired.filter((f) => f.kind === "captured").length;
  const deniedCount = fired.filter((f) => f.kind === "denied").length;
  const reduced = window.reduceMotion ? window.reduceMotion() : false;

  React.useEffect(() => () => timers.current.forEach(clearTimeout), []);
  React.useEffect(() => {
    if (listRef.current) listRef.current.scrollTop = listRef.current.scrollHeight;
  }, [fired]);
  React.useEffect(() => {
    onStateChange && onStateChange({ phase, done: phase === "done", denied: deniedCount });
  }, [phase, deniedCount]);

  function buildSequence() {
    const seq = [];
    let s = 0;
    for (let i = 0; i < cfg.burst; i++) {
      const captured = i < cfg.captured;
      if (captured) s += cfg.callCents;
      seq.push({ i: i + 1, kind: captured ? "captured" : "denied", spend: s });
    }
    return seq;
  }

  function run() {
    timers.current.forEach(clearTimeout);
    timers.current = [];
    const seq = buildSequence();
    if (reduced) { setFired(seq); setPhase("done"); return; }
    setFired([]); setPhase("running");
    seq.forEach((ev, idx) => {
      const t = setTimeout(() => {
        setFired((prev) => [...prev, ev]);
        if (idx === seq.length - 1) setPhase("done");
      }, 130 * (idx + 1));
      timers.current.push(t);
    });
  }
  function reset() {
    timers.current.forEach(clearTimeout);
    timers.current = [];
    setFired([]); setPhase("idle");
  }

  const pct = Math.min((spend / cfg.capCents) * 100, 100);
  const atCap = spend >= cfg.capCents;

  // live spend sparkline
  const spark = (() => {
    const W = 100, H = 30;
    if (fired.length < 2) return null;
    const max = cfg.capCents;
    const pts = fired.map((f, i) => {
      const x = (i / (cfg.burst - 1)) * W;
      const y = H - (f.spend / max) * (H - 3) - 1.5;
      return [x, y];
    });
    const d = pts.map((p, i) => (i ? "L" : "M") + p[0].toFixed(1) + " " + p[1].toFixed(1)).join(" ");
    return (
      <svg width="100%" height={H} viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="none" style={{ display: "block" }}>
        <line x1="0" y1="1.5" x2={W} y2="1.5" stroke="var(--danger-ink)" strokeWidth="1" strokeDasharray="2 2" opacity="0.5" />
        <path d={d} fill="none" stroke={atCap ? "var(--danger-ink)" : "var(--brand)"} strokeWidth="1.6" vectorEffect="non-scaling-stroke" strokeLinejoin="round" />
      </svg>
    );
  })();

  return (
    <div data-tour="overview-sim" style={{ display: "flex", flexDirection: "column", gap: 16, padding: 20, border: "1px solid var(--hairline)", borderRadius: "var(--radius)", background: "var(--surface-card)", boxShadow: "var(--shadow-sm)" }}>
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12, flexWrap: "wrap" }}>
        <div>
          <div style={{ fontSize: 16, fontWeight: 600, color: "var(--text-strong)", letterSpacing: "-0.01em" }}>Simulate a runaway agent</div>
          <div style={{ fontSize: 13, color: "var(--text-muted)", marginTop: 2 }}>
            <span style={{ fontFamily: "var(--font-mono)", fontSize: 12 }}>{cfg.agent}</span> fires a burst against your budget policy. Guardrails at machine speed — watch.
          </div>
        </div>
        {phase === "done"
          ? <Button variant="outline" size="sm" onClick={reset} data-tour="sim-reset">↺ Reset</Button>
          : <Button size="sm" onClick={run} disabled={phase === "running"} data-tour="simulate-btn">
              {phase === "running" ? "Simulating…" : "▷ Simulate a runaway agent"}
            </Button>}
      </div>

      {/* budget meter */}
      <div>
        <div style={{ display: "flex", justifyContent: "space-between", fontSize: 12, marginBottom: 6 }}>
          <span style={{ color: "var(--text-muted)" }}>budget policy · <span style={{ fontFamily: "var(--font-mono)" }}>prl_demo_budget_daily</span></span>
          <span style={{ fontFamily: "var(--font-mono)", fontWeight: 600, color: atCap ? "var(--danger-ink)" : "var(--text-strong)", fontVariantNumeric: "tabular-nums" }}>
            {D_sim.fmtUSD(spend)} / {D_sim.fmtUSD(cfg.capCents)}
          </span>
        </div>
        <div style={{ position: "relative", height: 12, borderRadius: 6, background: "var(--warning-fill)", border: "1px solid var(--hairline)", overflow: "hidden" }}>
          <div style={{
            width: pct + "%", height: "100%",
            background: atCap ? "var(--danger-ink)" : "var(--warning-ink)",
            opacity: atCap ? 0.9 : 0.85,
            transition: reduced ? "none" : "width 120ms linear, background 200ms",
          }}></div>
        </div>
      </div>

      <div className="cor-2col" style={{ display: "grid", gridTemplateColumns: "1.3fr 1fr", gap: 16, alignItems: "stretch" }}>
        {/* live event stream */}
        <div style={{ border: "1px solid var(--hairline)", borderRadius: "var(--radius-md)", overflow: "hidden", background: "var(--surface-card)" }}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "8px 12px", borderBottom: "1px solid var(--hairline)" }}>
            <span style={{ fontSize: 11, fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.04em", color: "var(--text-muted)" }}>live calls</span>
            <span style={{ fontFamily: "var(--font-mono)", fontSize: 11.5, color: "var(--text-muted)" }}>
              <span style={{ color: "var(--warning-ink)" }}>{capturedCount} captured</span> · <span style={{ color: deniedCount ? "var(--danger-ink)" : "var(--text-muted)" }}>{deniedCount} denied</span>
            </span>
          </div>
          <div ref={listRef} style={{ height: 150, overflowY: "auto", padding: "6px 0" }}>
            {fired.length === 0 ? (
              <div style={{ padding: "44px 12px", textAlign: "center", fontSize: 12.5, color: "var(--text-muted)" }}>Idle — press Simulate to fire a burst.</div>
            ) : fired.map((f) => (
              <div key={f.i} style={{ display: "flex", alignItems: "center", gap: 8, padding: "5px 12px", fontFamily: "var(--font-mono)", fontSize: 11.5 }}>
                <span style={{ color: "var(--text-muted)", width: 22 }}>#{f.i}</span>
                <span style={{ color: "var(--text-default)" }}>{cfg.meter}</span>
                <span style={{ color: "var(--text-muted)" }}>{D_sim.fmtUSD(cfg.callCents)}</span>
                <span style={{ marginLeft: "auto" }}>
                  {f.kind === "captured"
                    ? <Badge variant="warning">captured</Badge>
                    : <Badge variant="destructive">DENY</Badge>}
                </span>
              </div>
            ))}
          </div>
        </div>

        {/* spend sparkline + result */}
        <div style={{ display: "flex", flexDirection: "column", gap: 10, border: "1px solid var(--hairline)", borderRadius: "var(--radius-md)", padding: 12, background: "var(--surface-card)" }}>
          <span style={{ fontSize: 11, fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.04em", color: "var(--text-muted)" }}>spend vs. cap</span>
          <div style={{ flex: 1, display: "flex", alignItems: "center" }}>{spark || <div style={{ height: 30, width: "100%" }}></div>}</div>
          {phase === "done" ? (
            <div style={{ fontSize: 12.5, lineHeight: 1.45, color: "var(--text-strong)" }}>
              Budget policy blocked <span style={{ fontFamily: "var(--font-mono)", fontWeight: 600 }}>{deniedCount}</span> calls before execution — <span style={{ fontFamily: "var(--font-mono)", fontWeight: 600, color: "var(--success-ink)" }}>$0.00</span> over cap.
            </div>
          ) : (
            <div style={{ fontSize: 12.5, color: "var(--text-muted)" }}>
              {phase === "running" ? "Spend racing toward the cap…" : "The line flattens the instant the policy denies."}
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { RunawaySimulation });
