/* global React */
const { useState: useStateAL, useEffect: useEffectAL, useRef: useRefAL } = React;

// Animated agent loop: Perceive -> Think -> Act -> Observe
function AgentLoop({ autoplay = true, speed = 1500 }) {
  const STAGES = [
    { id: "input",  name: "User Input",   label: "01 / IN",     desc: "User asks a question or gives a goal.",          x: 30,  y: 40 },
    { id: "think",  name: "Reason",       label: "02 / THINK",  desc: "LLM reads context, decides what to do next.",    x: 280, y: 40 },
    { id: "act",    name: "Act (Tool)",   label: "03 / ACT",    desc: "Calls a tool with structured arguments.",        x: 530, y: 40 },
    { id: "obs",    name: "Observe",      label: "04 / OBS",    desc: "Tool returns a result; appended to context.",    x: 530, y: 200 },
    { id: "loop",   name: "Loop or Stop", label: "05 / LOOP",   desc: "Enough info? Reply. Otherwise, think again.",    x: 280, y: 200 },
    { id: "out",    name: "Final Answer", label: "06 / OUT",    desc: "Returns natural-language answer to user.",       x: 30,  y: 200 },
  ];

  const [step, setStep] = useStateAL(0);
  const [playing, setPlaying] = useStateAL(autoplay);
  const timer = useRefAL(null);

  useEffectAL(() => {
    if (!playing) return;
    timer.current = setInterval(() => {
      setStep(s => (s + 1) % STAGES.length);
    }, speed);
    return () => clearInterval(timer.current);
  }, [playing, speed]);

  const next = () => { setPlaying(false); setStep(s => (s + 1) % STAGES.length); };
  const prev = () => { setPlaying(false); setStep(s => (s - 1 + STAGES.length) % STAGES.length); };

  // SVG coordinates - the path connects all six nodes in a rounded loop
  const W = 720, H = 320;
  const NODE_W = 168, NODE_H = 84;
  const cx = (n) => n.x + NODE_W / 2;
  const cy = (n) => n.y + NODE_H / 2;

  // Build segments between consecutive stages
  const segments = STAGES.map((n, i) => {
    const next = STAGES[(i + 1) % STAGES.length];
    return { from: n, to: next, idx: i };
  });

  return (
    <Diagram
      title="The Agent Loop"
      controls={
        <>
          <button className="btn btn-icon ghost" onClick={prev} title="Previous">‹</button>
          <button className="btn ghost" onClick={() => setPlaying(p => !p)}>{playing ? "❚❚ Pause" : "▶ Play"}</button>
          <button className="btn btn-icon ghost" onClick={next} title="Next">›</button>
        </>
      }
    >
      <div className="agent-loop" style={{ height: H }}>
        <svg viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="xMidYMid meet">
          <defs>
            <marker id="arr" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto">
              <path d="M0,0 L10,5 L0,10 Z" className="flow-arrow" />
            </marker>
            <marker id="arrDim" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto">
              <path d="M0,0 L10,5 L0,10 Z" fill="var(--line-2)" />
            </marker>
          </defs>
          {segments.map((s) => {
            const isActive = step === s.idx;
            const fromX = cx(s.from), fromY = cy(s.from);
            const toX = cx(s.to),    toY = cy(s.to);
            // Compute connector path: prefer L-shape via midpoint
            let d;
            if (s.from.y === s.to.y) {
              // horizontal
              const dir = toX > fromX ? 1 : -1;
              const sx = fromX + (NODE_W / 2) * dir;
              const ex = toX - (NODE_W / 2) * dir;
              d = `M${sx},${fromY} L${ex},${toY}`;
            } else {
              // vertical
              const dir = toY > fromY ? 1 : -1;
              const sy = fromY + (NODE_H / 2) * dir;
              const ey = toY - (NODE_H / 2) * dir;
              d = `M${fromX},${sy} L${toX},${ey}`;
            }
            return (
              <path
                key={s.idx}
                d={d}
                stroke={isActive ? "var(--electric)" : "var(--line-2)"}
                strokeWidth={isActive ? 2.4 : 1.5}
                strokeDasharray={isActive ? "0" : "4 4"}
                fill="none"
                markerEnd={isActive ? "url(#arr)" : "url(#arrDim)"}
                style={{ transition: "stroke 220ms ease, stroke-width 220ms ease" }}
              />
            );
          })}
          {/* center label */}
          <text x={W/2} y={H/2 + 5} textAnchor="middle"
                fontFamily="var(--mono)" fontSize="11" fill="var(--ink-4)"
                letterSpacing="0.1em">
            REASON · ACT · OBSERVE
          </text>
        </svg>

        {STAGES.map((n, i) => (
          <div
            key={n.id}
            className={`loop-node ${step === i ? "active" : ""}`}
            style={{
              left: `${(n.x / W) * 100}%`,
              top: `${(n.y / H) * 100}%`,
              width: `${(NODE_W / W) * 100}%`,
            }}
          >
            <div className="label">{n.label}</div>
            <div className="name">{n.name}</div>
            <div className="desc">{n.desc}</div>
          </div>
        ))}
      </div>
      <div className="figure-caption">
        Step {step + 1} of {STAGES.length} · The agent keeps looping until the LLM decides it has enough information to answer.
      </div>
    </Diagram>
  );
}

window.AgentLoop = AgentLoop;
