/* anim-extras.jsx — Animations for the remaining topics */

/* ===== Tools & tool-calling ===== */
const ToolCallSim = () => {
  const TOOLS = [
    { name: "get_weather", args: ["city: str"], desc: "Returns current weather" },
    { name: "search_web", args: ["query: str"], desc: "Web search via Tavily" },
    { name: "send_email", args: ["to: str", "body: str"], desc: "Sends transactional email" },
  ];
  const FLOW = [
    { stage: "user", text: "What's the weather in Tokyo? Email it to alex@co.", color: "#1a1a1a" },
    { stage: "llm-think", text: "I need 2 tools: get_weather, then send_email", color: "#2d5fb8" },
    { stage: "tool-call", text: "get_weather(city='Tokyo')", color: "#2e7d4f", tool: 0 },
    { stage: "tool-result", text: "→ 18°C, light rain", color: "#2e7d4f" },
    { stage: "llm-think", text: "Now send the email with that result", color: "#2d5fb8" },
    { stage: "tool-call", text: "send_email(to='alex@co', body='Tokyo: 18°C, rain')", color: "#2e7d4f", tool: 2 },
    { stage: "tool-result", text: "→ message_id: msg_8a3f", color: "#2e7d4f" },
    { stage: "answer", text: "Sent ✓ Tokyo is 18°C with light rain.", color: "#1a1a1a" },
  ];
  const { step, containerRef } = useStepper({ steps: FLOW.length, intervalMs: 1400 });

  return (
    <div ref={containerRef}>
      <div style={{ display: "grid", gridTemplateColumns: "260px 1fr", gap: 20 }}>
        <div>
          <div style={{ fontFamily: "JetBrains Mono, monospace", fontSize: 11, color: "#6b6b66", marginBottom: 10, textTransform: "uppercase", letterSpacing: "0.06em" }}>tool registry</div>
          <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
            {TOOLS.map((t, i) => {
              const using = FLOW[step]?.tool === i;
              return (
                <div key={i} style={{
                  padding: "10px 12px",
                  background: using ? "#e3f1e8" : "#fff",
                  border: `1px solid ${using ? "#2e7d4f" : "#e7e7e2"}`,
                  borderRadius: 6, transition: "all 0.3s",
                }}>
                  <div style={{ fontFamily: "JetBrains Mono, monospace", fontSize: 12, color: using ? "#2e7d4f" : "#1a1a1a", fontWeight: 600 }}>{t.name}()</div>
                  <div style={{ fontFamily: "JetBrains Mono, monospace", fontSize: 10, color: "#a3a39d", marginTop: 2 }}>{t.args.join(", ")}</div>
                  <div style={{ fontSize: 11, color: "#6b6b66", marginTop: 4 }}>{t.desc}</div>
                </div>
              );
            })}
          </div>
        </div>
        <div>
          <div style={{ fontFamily: "JetBrains Mono, monospace", fontSize: 11, color: "#6b6b66", marginBottom: 10, textTransform: "uppercase", letterSpacing: "0.06em" }}>execution trace</div>
          <div style={{ background: "#fff", border: "1px solid #e7e7e2", borderRadius: 6, padding: 12, display: "flex", flexDirection: "column", gap: 6, maxHeight: 320, overflow: "auto" }}>
            {FLOW.slice(0, step + 1).map((f, i) => (
              <div key={i} style={{
                padding: "6px 10px",
                fontFamily: "JetBrains Mono, monospace", fontSize: 11,
                color: f.color,
                background: i === step ? "#fbfbfa" : "transparent",
                border: i === step ? "1px solid #e7e7e2" : "1px solid transparent",
                borderRadius: 3,
                animation: i === step ? "slideIn 0.3s" : undefined,
              }}>
                <span style={{ color: "#a3a39d", marginRight: 8 }}>[{f.stage}]</span>
                {f.text}
              </div>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
};

/* ===== RAG pipeline ===== */
const RAGSim = () => {
  const STAGES = [
    { name: "ingest", desc: "Load 50 docs · split into 320 chunks", out: "320 chunks" },
    { name: "embed", desc: "Each chunk → 1536-dim vector", out: "320 vectors" },
    { name: "store", desc: "Index in pgvector / Pinecone", out: "indexed ✓" },
    { name: "query", desc: "User: 'What's our refund policy?'", out: "1 query" },
    { name: "retrieve", desc: "kNN search · top 4 chunks", out: "4 contexts" },
    { name: "generate", desc: "LLM(prompt + contexts + question)", out: "grounded answer" },
  ];
  const { step, containerRef } = useStepper({ steps: STAGES.length, intervalMs: 1400 });
  const isIndex = step < 3;
  const isQuery = step >= 3;
  return (
    <div ref={containerRef}>
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
        <div style={{ background: isIndex ? "#fff" : "#fbfbfa", opacity: isIndex ? 1 : 0.5, border: "1px solid #e7e7e2", borderRadius: 8, padding: 16, transition: "all 0.3s" }}>
          <div style={{ fontFamily: "JetBrains Mono, monospace", fontSize: 11, color: "#2d5fb8", marginBottom: 12, textTransform: "uppercase", letterSpacing: "0.06em" }}>indexing pipeline · offline</div>
          {STAGES.slice(0, 3).map((s, i) => (
            <div key={i} style={{ display: "flex", alignItems: "center", gap: 10, padding: "8px 0", opacity: step >= i ? 1 : 0.3 }}>
              <div style={{ width: 24, height: 24, borderRadius: "50%", background: step > i ? "#2d5fb8" : step === i ? "#fff" : "#fbfbfa", border: `1.5px solid ${step >= i ? "#2d5fb8" : "#c7c7c0"}`, color: step > i ? "#fff" : "#2d5fb8", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 11, fontFamily: "JetBrains Mono, monospace", fontWeight: 600 }}>{i+1}</div>
              <div style={{ flex: 1 }}>
                <div style={{ fontFamily: "JetBrains Mono, monospace", fontSize: 12, color: "#1a1a1a", fontWeight: 600 }}>{s.name}</div>
                <div style={{ fontSize: 11, color: "#6b6b66" }}>{s.desc}</div>
              </div>
              <div style={{ fontFamily: "JetBrains Mono, monospace", fontSize: 11, color: step > i ? "#2e7d4f" : "#a3a39d" }}>{step > i ? `→ ${s.out}` : "—"}</div>
            </div>
          ))}
        </div>
        <div style={{ background: isQuery ? "#fff" : "#fbfbfa", opacity: isQuery ? 1 : 0.5, border: "1px solid #e7e7e2", borderRadius: 8, padding: 16, transition: "all 0.3s" }}>
          <div style={{ fontFamily: "JetBrains Mono, monospace", fontSize: 11, color: "#c7521c", marginBottom: 12, textTransform: "uppercase", letterSpacing: "0.06em" }}>query pipeline · per request</div>
          {STAGES.slice(3).map((s, i) => {
            const idx = i + 3;
            return (
              <div key={i} style={{ display: "flex", alignItems: "center", gap: 10, padding: "8px 0", opacity: step >= idx ? 1 : 0.3 }}>
                <div style={{ width: 24, height: 24, borderRadius: "50%", background: step > idx ? "#c7521c" : step === idx ? "#fff" : "#fbfbfa", border: `1.5px solid ${step >= idx ? "#c7521c" : "#c7c7c0"}`, color: step > idx ? "#fff" : "#c7521c", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 11, fontFamily: "JetBrains Mono, monospace", fontWeight: 600 }}>{i+1}</div>
                <div style={{ flex: 1 }}>
                  <div style={{ fontFamily: "JetBrains Mono, monospace", fontSize: 12, color: "#1a1a1a", fontWeight: 600 }}>{s.name}</div>
                  <div style={{ fontSize: 11, color: "#6b6b66" }}>{s.desc}</div>
                </div>
                <div style={{ fontFamily: "JetBrains Mono, monospace", fontSize: 11, color: step > idx ? "#2e7d4f" : "#a3a39d" }}>{step > idx ? `→ ${s.out}` : "—"}</div>
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
};

/* ===== Reasoning patterns: ReAct vs Reflection vs Plan-and-Execute ===== */
const ReasoningSim = () => {
  const PATTERNS = [
    {
      name: "ReAct",
      sub: "Thought → Action → Observation, repeat",
      color: "#2d5fb8",
      trace: [
        { kind: "Thought", text: "User wants Apple's stock price. I should search." },
        { kind: "Action", text: "search('AAPL stock price today')" },
        { kind: "Observation", text: "$245.30, +1.2%" },
        { kind: "Thought", text: "I have the info. Respond." },
        { kind: "Answer", text: "Apple is trading at $245.30, up 1.2%." },
      ],
    },
    {
      name: "Reflection",
      sub: "Generate → Critique → Revise",
      color: "#c7521c",
      trace: [
        { kind: "Draft", text: "Apple stock went up." },
        { kind: "Critique", text: "Vague. Missing price, %, time-frame." },
        { kind: "Revise", text: "AAPL closed at $245.30, +1.2% today." },
        { kind: "Critique", text: "Better. Self-consistent. Ship." },
        { kind: "Answer", text: "AAPL closed at $245.30, +1.2% today." },
      ],
    },
    {
      name: "Plan-and-Execute",
      sub: "Plan all steps upfront, then execute serially",
      color: "#2e7d4f",
      trace: [
        { kind: "Plan", text: "1) Get price 2) Get % change 3) Format response" },
        { kind: "Execute 1", text: "get_quote('AAPL') → $245.30" },
        { kind: "Execute 2", text: "get_change('AAPL', '1d') → +1.2%" },
        { kind: "Execute 3", text: "Compose answer" },
        { kind: "Answer", text: "AAPL: $245.30 (+1.2%)" },
      ],
    },
  ];
  const [active, setActive] = useState(0);
  const cur = PATTERNS[active];
  const STEPS = cur.trace.length;
  const { step, containerRef, reset } = useStepper({ steps: STEPS, intervalMs: 1300 });
  useEffect(() => { reset(); /* eslint-disable-next-line */ }, [active]);

  return (
    <div ref={containerRef}>
      <div style={{ display: "flex", gap: 6, marginBottom: 16 }}>
        {PATTERNS.map((p, i) => (
          <button key={i} onClick={() => setActive(i)} style={{
            padding: "8px 14px", borderRadius: 4,
            border: "1px solid", borderColor: active === i ? p.color : "#e7e7e2",
            background: active === i ? p.color : "#fff",
            color: active === i ? "#fff" : "#3d3d3a",
            fontSize: 12, fontFamily: "Inter Tight, sans-serif", cursor: "pointer", fontWeight: 600,
          }}>{p.name}</button>
        ))}
      </div>
      <div style={{ fontSize: 13, color: "#6b6b66", marginBottom: 12, fontStyle: "italic" }}>{cur.sub}</div>
      <div style={{ background: "#fff", border: "1px solid #e7e7e2", borderRadius: 8, padding: 16, display: "flex", flexDirection: "column", gap: 6 }}>
        {cur.trace.slice(0, step + 1).map((t, i) => (
          <div key={i} style={{
            display: "grid", gridTemplateColumns: "100px 1fr",
            gap: 12, padding: "8px 12px",
            background: i === step ? "#fbfbfa" : "transparent",
            border: i === step ? "1px solid #e7e7e2" : "1px solid transparent",
            borderRadius: 4,
            animation: i === step ? "slideIn 0.3s" : undefined,
          }}>
            <div style={{ fontFamily: "JetBrains Mono, monospace", fontSize: 11, color: cur.color, fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.04em" }}>{t.kind}</div>
            <div style={{ fontSize: 13, color: "#1a1a1a" }}>{t.text}</div>
          </div>
        ))}
      </div>
    </div>
  );
};

/* ===== LangSmith / Tracing waterfall ===== */
const TracingSim = () => {
  const SPANS = [
    { name: "agent.invoke",            depth: 0, start: 0,   dur: 4200, kind: "graph",   tokens: null },
    { name: "classify_intent",         depth: 1, start: 50,  dur: 380,  kind: "node",    tokens: null },
    { name: "ChatAnthropic.invoke",    depth: 2, start: 80,  dur: 320,  kind: "llm",     tokens: 412 },
    { name: "tool_use",                depth: 1, start: 460, dur: 1200, kind: "node",    tokens: null },
    { name: "search.invoke",           depth: 2, start: 480, dur: 1100, kind: "tool",    tokens: null },
    { name: "respond",                 depth: 1, start: 1700, dur: 2480, kind: "node",   tokens: null },
    { name: "ChatAnthropic.invoke",    depth: 2, start: 1740, dur: 2400, kind: "llm",    tokens: 1042 },
  ];
  const TOTAL = 4200;
  const KIND_COLOR = { graph: "#1a1a1a", node: "#2d5fb8", llm: "#c7521c", tool: "#2e7d4f" };
  const { step, containerRef } = useStepper({ steps: SPANS.length, intervalMs: 700 });

  return (
    <div ref={containerRef}>
      <div style={{ background: "#fff", border: "1px solid #e7e7e2", borderRadius: 8, padding: 16 }}>
        <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 12 }}>
          <div style={{ fontFamily: "JetBrains Mono, monospace", fontSize: 11, color: "#6b6b66", textTransform: "uppercase", letterSpacing: "0.06em" }}>trace · run_5f2c8a · 4.2s · $0.0048</div>
          <div style={{ fontFamily: "JetBrains Mono, monospace", fontSize: 11, color: "#6b6b66" }}>1454 tokens</div>
        </div>
        <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
          {SPANS.slice(0, step + 1).map((s, i) => (
            <div key={i} style={{
              display: "grid", gridTemplateColumns: "220px 1fr 80px",
              gap: 12, alignItems: "center",
              animation: i === step ? "slideIn 0.3s" : undefined,
            }}>
              <div style={{ paddingLeft: s.depth * 14, fontFamily: "JetBrains Mono, monospace", fontSize: 11, color: "#1a1a1a", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
                <span style={{ color: KIND_COLOR[s.kind], marginRight: 6 }}>▸</span>
                {s.name}
              </div>
              <div style={{ position: "relative", height: 18, background: "#f4f4f1", borderRadius: 2 }}>
                <div style={{
                  position: "absolute", left: `${(s.start/TOTAL)*100}%`, width: `${(s.dur/TOTAL)*100}%`,
                  height: "100%", background: KIND_COLOR[s.kind], borderRadius: 2,
                  display: "flex", alignItems: "center", justifyContent: "flex-start",
                  paddingLeft: 6, color: "#fff", fontSize: 9, fontFamily: "JetBrains Mono, monospace",
                  overflow: "hidden", whiteSpace: "nowrap",
                }}>{s.dur}ms</div>
              </div>
              <div style={{ fontFamily: "JetBrains Mono, monospace", fontSize: 10, color: "#6b6b66", textAlign: "right" }}>{s.tokens ? `${s.tokens} tok` : `${s.dur}ms`}</div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
};

/* ===== Subgraphs / composition ===== */
const SubgraphSim = () => {
  const STEPS = [
    { focus: "main", node: "router", desc: "main graph routes by query type" },
    { focus: "research", node: "search", desc: "subgraph: research_team starts" },
    { focus: "research", node: "fact_check", desc: "subgraph: fact-checker validates" },
    { focus: "main", node: "writer", desc: "control returns to main with research result" },
    { focus: "main", node: "END", desc: "main graph completes" },
  ];
  const { step, containerRef } = useStepper({ steps: STEPS.length, intervalMs: 1500 });
  const cur = STEPS[step];
  return (
    <div ref={containerRef}>
      <svg viewBox="0 0 600 280" style={{ width: "100%", height: "auto", background: "#fbfbfa", borderRadius: 8, border: "1px solid #e7e7e2" }}>
        {/* Subgraph container */}
        <rect x={210} y={30} width="220" height="180" rx="10"
          fill={cur.focus === "research" ? "#fff" : "#f4f4f1"}
          stroke={cur.focus === "research" ? "#2d5fb8" : "#c7c7c0"}
          strokeWidth="1.5" strokeDasharray="4 3"
          style={{ transition: "all 0.3s" }} />
        <text x={320} y={50} textAnchor="middle"
          fontSize="10" fontFamily="JetBrains Mono, monospace"
          fill={cur.focus === "research" ? "#2d5fb8" : "#a3a39d"} fontWeight="600"
          letterSpacing="0.06em">
          SUBGRAPH · research_team
        </text>

        {/* Main nodes */}
        {[
          { id: "router",     x: 80,  y: 120, label: "router" },
          { id: "writer",     x: 520, y: 120, label: "writer" },
          { id: "END",        x: 520, y: 240, label: "END" },
        ].map(n => {
          const active = cur.node === n.id && cur.focus === "main";
          return (
            <g key={n.id}>
              <circle cx={n.x} cy={n.y} r="32"
                fill={active ? "#fbeadc" : "#fff"}
                stroke={active ? "#c7521c" : "#c7c7c0"} strokeWidth={active ? 2 : 1}
                style={{ transition: "all 0.3s" }} />
              <text x={n.x} y={n.y + 4} textAnchor="middle"
                fontSize="11" fontFamily="JetBrains Mono, monospace"
                fill={active ? "#c7521c" : "#1a1a1a"} fontWeight="600">{n.label}</text>
            </g>
          );
        })}

        {/* Subgraph nodes */}
        {[
          { id: "search",     x: 270, y: 120, label: "search" },
          { id: "fact_check", x: 370, y: 120, label: "fact_check" },
        ].map(n => {
          const active = cur.node === n.id;
          return (
            <g key={n.id}>
              <circle cx={n.x} cy={n.y} r="28"
                fill={active ? "#e8f0fe" : "#fff"}
                stroke={active ? "#2d5fb8" : "#c7c7c0"} strokeWidth={active ? 2 : 1}
                style={{ transition: "all 0.3s" }} />
              <text x={n.x} y={n.y + 4} textAnchor="middle"
                fontSize="10" fontFamily="JetBrains Mono, monospace"
                fill={active ? "#2d5fb8" : "#1a1a1a"}>{n.label}</text>
            </g>
          );
        })}

        {/* Edges */}
        <line x1={112} y1={120} x2={242} y2={120} stroke="#c7c7c0" strokeWidth="1.5" />
        <line x1={298} y1={120} x2={342} y2={120} stroke="#c7c7c0" strokeWidth="1.5" />
        <line x1={398} y1={120} x2={488} y2={120} stroke="#c7c7c0" strokeWidth="1.5" />
        <line x1={520} y1={152} x2={520} y2={208} stroke="#c7c7c0" strokeWidth="1.5" />
      </svg>
      <div style={{ marginTop: 12, padding: "10px 14px", background: "#fff", border: "1px solid #e7e7e2", borderRadius: 6, fontSize: 13, color: "#1a1a1a" }}>
        <span style={{ fontFamily: "JetBrains Mono, monospace", fontSize: 11, color: "#6b6b66", marginRight: 8 }}>step {step+1}/{STEPS.length}:</span>
        {cur.desc}
      </div>
    </div>
  );
};

window.ToolCallSim = ToolCallSim;
window.RAGSim = RAGSim;
window.ReasoningSim = ReasoningSim;
window.TracingSim = TracingSim;
window.SubgraphSim = SubgraphSim;
