/* global React */
const { useState: useState_d, useEffect: useEffect_d, useRef: useRef_d } = React;

/* ============================================================
   AgentOpsDiagram
   --------------
   Animated diagram showing how humans, agents, and systems
   actually work together. Tokens (small dots) flow from a
   "request" node through humans → agents → systems → back.
   ============================================================ */

function AgentOpsDiagram() {
  const [tick, setTick] = useState_d(0);
  const [hovered, setHovered] = useState_d(null);

  useEffect_d(() => {
    let raf;
    let last = performance.now();
    const loop = (now) => {
      // Throttle to ~30fps; tick is just a counter the SVG uses for staggered animations
      if (now - last > 33) { setTick(t => t + 1); last = now; }
      raf = requestAnimationFrame(loop);
    };
    raf = requestAnimationFrame(loop);
    return () => cancelAnimationFrame(raf);
  }, []);

  // Layout constants in viewBox units
  const W = 760, H = 480;
  // Three columns: Humans (left), Agents (middle), Systems (right)
  const cols = {
    human:   { x: 140, label: "HUMANS" },
    agent:   { x: 380, label: "AGENTS" },
    system:  { x: 620, label: "SYSTEMS" },
  };

  // Nodes
  const humans = [
    { id: "ops",   y: 130, name: "Ops lead",       sub: "approves" },
    { id: "sales", y: 230, name: "Sales rep",      sub: "asks" },
    { id: "exec",  y: 330, name: "Exec",           sub: "reviews" },
  ];
  const agents = [
    { id: "intake",   y: 110, name: "Intake agent",    sub: "routes work" },
    { id: "research", y: 210, name: "Research agent",  sub: "gathers" },
    { id: "execute",  y: 310, name: "Execution agent", sub: "acts" },
    { id: "audit",    y: 400, name: "Audit agent",     sub: "verifies" },
  ];
  const systems = [
    { id: "crm",      y: 130, name: "CRM",          sub: "Zoho" },
    { id: "payments", y: 230, name: "Payments",     sub: "Priority" },
    { id: "warehouse",y: 330, name: "Warehouse",    sub: "BigQuery" },
  ];

  // Edges (logical)
  const edges = [
    // Humans -> intake agent
    { from: ["human", 130], to: ["agent", 110], kind: "request" },
    { from: ["human", 230], to: ["agent", 110], kind: "request" },
    { from: ["human", 330], to: ["agent", 110], kind: "request" },
    // intake -> research/execute/audit
    { from: ["agent", 110], to: ["agent", 210], kind: "internal" },
    { from: ["agent", 110], to: ["agent", 310], kind: "internal" },
    { from: ["agent", 210], to: ["agent", 310], kind: "internal" },
    { from: ["agent", 310], to: ["agent", 400], kind: "internal" },
    // execute -> systems
    { from: ["agent", 310], to: ["system", 130], kind: "action" },
    { from: ["agent", 310], to: ["system", 230], kind: "action" },
    { from: ["agent", 310], to: ["system", 330], kind: "action" },
    // research <- systems
    { from: ["system", 230], to: ["agent", 210], kind: "data" },
    { from: ["system", 330], to: ["agent", 210], kind: "data" },
    // audit -> exec human
    { from: ["agent", 400], to: ["human", 330], kind: "report" },
    // intake -> ops human (status pings)
    { from: ["agent", 110], to: ["human", 130], kind: "report" },
    // research -> sales human (findings)
    { from: ["agent", 210], to: ["human", 230], kind: "report" },
  ];

  // Compute pixel coords
  const xy = (col, y) => ({ x: cols[col].x, y });

  // Token animation: each token has a path index (which edge) and a start tick offset
  const NUM_TOKENS = 12;
  const TOKEN_PERIOD = 90; // ticks
  const tokens = [];
  for (let i = 0; i < NUM_TOKENS; i++) {
    const edgeIdx = i % edges.length;
    const offset = (i * 17) % TOKEN_PERIOD;
    const phase = ((tick + offset) % TOKEN_PERIOD) / TOKEN_PERIOD; // 0→1
    tokens.push({ edgeIdx, phase });
  }

  const colors = {
    request: "var(--rust)",
    internal: "var(--teal)",
    action: "var(--rust)",
    data: "var(--teal)",
    report: "var(--ink)",
  };

  // Render
  return (
    <div className="aod-wrap">
      <svg viewBox={`0 0 ${W} ${H}`} className="aod-svg" preserveAspectRatio="xMidYMid meet">
        <defs>
          <pattern id="aod-grid" width="24" height="24" patternUnits="userSpaceOnUse">
            <path d="M24 0H0V24" fill="none" stroke="var(--line-soft)" strokeWidth="0.5" />
          </pattern>
          <filter id="aod-glow" x="-50%" y="-50%" width="200%" height="200%">
            <feGaussianBlur stdDeviation="2" result="b" />
            <feMerge><feMergeNode in="b" /><feMergeNode in="SourceGraphic" /></feMerge>
          </filter>
        </defs>

        {/* Background grid */}
        <rect x="0" y="0" width={W} height={H} fill="url(#aod-grid)" opacity="0.5" />

        {/* Column headers */}
        {Object.entries(cols).map(([key, c]) => (
          <g key={key}>
            <text x={c.x} y={36} textAnchor="middle"
                  fontFamily="var(--font-mono)" fontSize="11"
                  fill="var(--muted)" letterSpacing="2">
              {c.label}
            </text>
            <line x1={c.x - 80} y1={48} x2={c.x + 80} y2={48}
                  stroke="var(--line)" strokeWidth="0.5" />
          </g>
        ))}

        {/* Edges */}
        {edges.map((e, i) => {
          const a = xy(e.from[0], e.from[1]);
          const b = xy(e.to[0],   e.to[1]);
          // Curve: cubic with horizontal control offset
          const dx = (b.x - a.x);
          const mx1 = a.x + dx * 0.5;
          const mx2 = b.x - dx * 0.5;
          const path = `M ${a.x} ${a.y} C ${mx1} ${a.y}, ${mx2} ${b.y}, ${b.x} ${b.y}`;
          return (
            <path
              key={i}
              d={path}
              fill="none"
              stroke={colors[e.kind]}
              strokeWidth={hovered === e.kind ? 1.4 : 0.8}
              strokeOpacity={hovered && hovered !== e.kind ? 0.15 : 0.35}
              strokeLinecap="round"
              data-edge={i}
            />
          );
        })}

        {/* Tokens flowing along edges */}
        {tokens.map((tok, i) => {
          const e = edges[tok.edgeIdx];
          const a = xy(e.from[0], e.from[1]);
          const b = xy(e.to[0],   e.to[1]);
          const dx = (b.x - a.x);
          const mx1 = a.x + dx * 0.5;
          const mx2 = b.x - dx * 0.5;
          // Approximate cubic Bezier point at phase t
          const t = tok.phase;
          const omt = 1 - t;
          const x = omt*omt*omt*a.x + 3*omt*omt*t*mx1 + 3*omt*t*t*mx2 + t*t*t*b.x;
          const y = omt*omt*omt*a.y + 3*omt*omt*t*a.y + 3*omt*t*t*b.y + t*t*t*b.y;
          // Fade in/out
          const fadeIn  = Math.min(1, t * 6);
          const fadeOut = Math.min(1, (1 - t) * 6);
          const opacity = Math.min(fadeIn, fadeOut);
          return (
            <circle
              key={i}
              cx={x} cy={y} r="3"
              fill={colors[e.kind]}
              opacity={hovered && hovered !== e.kind ? opacity * 0.2 : opacity}
              filter="url(#aod-glow)"
            />
          );
        })}

        {/* Humans column */}
        {humans.map(h => (
          <g key={h.id}>
            <circle cx={cols.human.x} cy={h.y} r="22" fill="var(--card)" stroke="var(--ink)" strokeWidth="1" />
            {/* Simple human glyph: head + shoulders */}
            <circle cx={cols.human.x} cy={h.y - 4} r="5" fill="var(--ink)" />
            <path d={`M ${cols.human.x - 8} ${h.y + 8} Q ${cols.human.x} ${h.y - 2}, ${cols.human.x + 8} ${h.y + 8}`}
                  fill="none" stroke="var(--ink)" strokeWidth="2" strokeLinecap="round" />
            <text x={cols.human.x - 36} y={h.y + 1} textAnchor="end"
                  fontFamily="var(--font-body)" fontSize="13" fontWeight="500" fill="var(--ink)">
              {h.name}
            </text>
            <text x={cols.human.x - 36} y={h.y + 15} textAnchor="end"
                  fontFamily="var(--font-mono)" fontSize="10" fill="var(--muted)">
              {h.sub}
            </text>
          </g>
        ))}

        {/* Agents column — diamond-ish nodes */}
        {agents.map(a => {
          const pulse = ((tick + a.y) % 60) / 60;
          const r = 24 + Math.sin(pulse * Math.PI * 2) * 1.5;
          return (
            <g key={a.id}>
              <circle cx={cols.agent.x} cy={a.y} r={r + 6} fill="var(--rust)" opacity={0.08 + Math.sin(pulse * Math.PI * 2) * 0.04} />
              <circle cx={cols.agent.x} cy={a.y} r={r} fill="var(--paper)" stroke="var(--rust)" strokeWidth="1.5" />
              {/* Agent glyph: small spark */}
              <path d={`M ${cols.agent.x} ${a.y - 8} L ${cols.agent.x + 5} ${a.y} L ${cols.agent.x} ${a.y + 8} L ${cols.agent.x - 5} ${a.y} Z`}
                    fill="var(--rust)" />
              <text x={cols.agent.x} y={a.y + 42} textAnchor="middle"
                    fontFamily="var(--font-body)" fontSize="12" fontWeight="500" fill="var(--ink)">
                {a.name}
              </text>
              <text x={cols.agent.x} y={a.y + 56} textAnchor="middle"
                    fontFamily="var(--font-mono)" fontSize="10" fill="var(--muted)">
                {a.sub}
              </text>
            </g>
          );
        })}

        {/* Systems column — square chips */}
        {systems.map(s => (
          <g key={s.id}>
            <rect x={cols.system.x - 22} y={s.y - 22} width="44" height="44"
                  fill="var(--card)" stroke="var(--teal)" strokeWidth="1" rx="6" />
            {/* System glyph: server stripes */}
            <rect x={cols.system.x - 12} y={s.y - 10} width="24" height="4" fill="var(--teal)" />
            <rect x={cols.system.x - 12} y={s.y - 2}  width="24" height="4" fill="var(--teal)" opacity="0.6" />
            <rect x={cols.system.x - 12} y={s.y + 6}  width="24" height="4" fill="var(--teal)" opacity="0.3" />
            <text x={cols.system.x + 36} y={s.y + 1}
                  fontFamily="var(--font-body)" fontSize="13" fontWeight="500" fill="var(--ink)">
              {s.name}
            </text>
            <text x={cols.system.x + 36} y={s.y + 15}
                  fontFamily="var(--font-mono)" fontSize="10" fill="var(--muted)">
              {s.sub}
            </text>
          </g>
        ))}
      </svg>

      <div className="aod-legend">
        {[
          { kind: "request",  label: "Requests in" },
          { kind: "internal", label: "Agent handoff" },
          { kind: "action",   label: "Writes / actions" },
          { kind: "data",     label: "Reads / data" },
          { kind: "report",   label: "Back to humans" },
        ].map(item => (
          <button
            key={item.kind}
            type="button"
            onMouseEnter={() => setHovered(item.kind)}
            onMouseLeave={() => setHovered(null)}
            className={`aod-legend-item${hovered === item.kind ? " is-active" : ""}`}
          >
            <span className="aod-legend-dot" style={{ background: colors[item.kind] }} />
            {item.label}
          </button>
        ))}
      </div>
    </div>
  );
}

window.AgentOpsDiagram = AgentOpsDiagram;
