/* global React */
const { useState: useStateMCP, useEffect: useEffectMCP, useRef: useRefMCP } = React;

function MCPDiagram() {
  // Animated message flow between Host (LangChain) and N MCP servers
  const [step, setStep] = useStateMCP(0);
  const [playing, setPlaying] = useStateMCP(true);

  useEffectMCP(() => {
    if (!playing) return;
    const t = setInterval(() => setStep(s => (s + 1) % MESSAGES.length), 1700);
    return () => clearInterval(t);
  }, [playing]);

  const MESSAGES = [
    { dir: "h2s", srv: 0, label: "list_tools()", color: "var(--electric)" },
    { dir: "s2h", srv: 0, label: "[ search_repos, read_file, ... ]", color: "var(--violet)" },
    { dir: "h2s", srv: 1, label: "list_tools()", color: "var(--electric)" },
    { dir: "s2h", srv: 1, label: "[ query, list_tables ]", color: "var(--violet)" },
    { dir: "h2s", srv: 0, label: "call: read_file({path})", color: "var(--electric)" },
    { dir: "s2h", srv: 0, label: "→ file contents", color: "var(--violet)" },
    { dir: "h2s", srv: 1, label: "call: query({sql})", color: "var(--electric)" },
    { dir: "s2h", srv: 1, label: "→ rows[]", color: "var(--violet)" },
  ];

  const SERVERS = [
    { name: "github-mcp",   sub: "stdio · npx @modelcontextprotocol/server-github", tools: ["search_repos", "read_file", "create_issue"] },
    { name: "postgres-mcp", sub: "stdio · python -m mcp_postgres",                  tools: ["query", "list_tables", "schema"] },
  ];

  const cur = MESSAGES[step];

  // SVG dimensions
  const W = 760, H = 360;
  const HOST = { x: 40, y: 130, w: 220, h: 120 };
  const SRV  = (i) => ({ x: 500, y: 60 + i * 160, w: 220, h: 120 });

  return (
    <Diagram
      title="MCP · Host ↔ Servers"
      controls={
        <button className="btn ghost" onClick={() => setPlaying(p => !p)}>{playing ? "❚❚ Pause" : "▶ Play"}</button>
      }
    >
      <div className="mcp-stage" style={{ padding: 0, height: H }}>
        <svg viewBox={`0 0 ${W} ${H}`} width="100%" height="100%">
          <defs>
            <marker id="mcpArr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto">
              <path d="M0,0 L10,5 L0,10 Z" fill={cur.color} />
            </marker>
          </defs>

          {/* Host (LangChain MCP Adapter) */}
          <g>
            <rect x={HOST.x} y={HOST.y} width={HOST.w} height={HOST.h} rx="10"
                  fill="white" stroke="var(--electric)" strokeWidth="1.5" />
            <text x={HOST.x + 14} y={HOST.y + 22} fontFamily="var(--mono)" fontSize="10"
                  fill="var(--ink-3)" letterSpacing="1">HOST · LANGCHAIN</text>
            <text x={HOST.x + 14} y={HOST.y + 46} fontFamily="var(--sans)" fontSize="14"
                  fontWeight="600" fill="var(--ink)">MCP Adapter</text>
            <text x={HOST.x + 14} y={HOST.y + 66} fontFamily="var(--mono)" fontSize="11"
                  fill="var(--ink-3)">langchain_mcp_adapters</text>
            <text x={HOST.x + 14} y={HOST.y + 92} fontFamily="var(--sans)" fontSize="11"
                  fill="var(--ink-2)">Discovers tools · Routes calls</text>
            <text x={HOST.x + 14} y={HOST.y + 108} fontFamily="var(--sans)" fontSize="11"
                  fill="var(--ink-2)">Surfaces them as LangChain Tools</text>
          </g>

          {/* Servers */}
          {SERVERS.map((s, i) => {
            const r = SRV(i);
            const isActive = cur.srv === i;
            return (
              <g key={i}>
                <rect x={r.x} y={r.y} width={r.w} height={r.h} rx="10"
                      fill="white" stroke={isActive ? "var(--violet)" : "var(--line)"}
                      strokeWidth={isActive ? 1.8 : 1.2}
                      style={{ transition: "stroke 200ms" }} />
                <text x={r.x + 14} y={r.y + 22} fontFamily="var(--mono)" fontSize="10"
                      fill="var(--ink-3)" letterSpacing="1">MCP SERVER</text>
                <text x={r.x + 14} y={r.y + 46} fontFamily="var(--sans)" fontSize="14"
                      fontWeight="600" fill="var(--ink)">{s.name}</text>
                <text x={r.x + 14} y={r.y + 64} fontFamily="var(--mono)" fontSize="10"
                      fill="var(--ink-3)">{s.sub}</text>
                {s.tools.map((t, j) => (
                  <text key={j} x={r.x + 14} y={r.y + 86 + j * 14} fontFamily="var(--mono)"
                        fontSize="11" fill="var(--ink-2)">· {t}</text>
                ))}
              </g>
            );
          })}

          {/* Animated message line */}
          {(() => {
            const r = SRV(cur.srv);
            const fromX = cur.dir === "h2s" ? HOST.x + HOST.w : r.x;
            const fromY = cur.dir === "h2s" ? HOST.y + HOST.h / 2 : r.y + r.h / 2;
            const toX   = cur.dir === "h2s" ? r.x : HOST.x + HOST.w;
            const toY   = cur.dir === "h2s" ? r.y + r.h / 2 : HOST.y + HOST.h / 2;
            const midX = (fromX + toX) / 2;
            const midY = (fromY + toY) / 2 - 30;
            const d = `M${fromX},${fromY} Q${midX},${midY} ${toX},${toY}`;
            return (
              <>
                <path d={d} stroke={cur.color} strokeWidth="2" fill="none"
                      markerEnd="url(#mcpArr)" strokeDasharray="6 4">
                  <animate attributeName="stroke-dashoffset" from="20" to="0" dur="1.4s" repeatCount="indefinite" />
                </path>
                <rect x={midX - 90} y={midY - 18} width="180" height="26" rx="13"
                      fill="white" stroke={cur.color} strokeWidth="1.2" />
                <text x={midX} y={midY - 1} textAnchor="middle"
                      fontFamily="var(--mono)" fontSize="11" fill={cur.color}>
                  {cur.dir === "h2s" ? "→ " : "← "}{cur.label}
                </text>
              </>
            );
          })()}
        </svg>
      </div>
      <div className="figure-caption">
        JSON-RPC 2.0 over stdio (or SSE) · The host discovers tools, then dispatches calls. The agent never knows it's MCP.
      </div>
    </Diagram>
  );
}

window.MCPDiagram = MCPDiagram;
