/* NeuralVault — engines.jsx
   Dual Command Center: TrafficEngine (left) + VisionEngine (right).
   Shared chrome: EngineFrame, EngineHeader, ReadoutGrid, Ticker. */

const { useState, useEffect, useRef } = React;

/* ---------- shared clock ---------- */
function useUtcClock() {
  const [now, setNow] = useState(() => new Date());
  useEffect(() => {
    const id = setInterval(() => setNow(new Date()), 1000);
    return () => clearInterval(id);
  }, []);
  return now;
}
const pad = (n) => n.toString().padStart(2, "0");
const fmtUtc = (d) => `UTC ${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())}:${pad(d.getUTCSeconds())}`;

/* ---------- EngineFrame: outer chrome shared by both engines ---------- */
function EngineFrame({ kicker, label, statusText = "LIVE", children, readout, ref_ }) {
  return (
    <div className="engine-frame">
      <div className="engine-head">
        <span><span className="dot" />{kicker}</span>
        <span className="mono">{ref_}</span>
      </div>

      <div className="engine">
        <div className="engine-bar">
          <div className="tabs">
            <span className="tab on">{label}</span>
          </div>
          <span>● {statusText}</span>
        </div>
        <div className="engine-canvas">{children}</div>
        <div className="engine-readout">{readout}</div>
      </div>
    </div>
  );
}

/* ====================================================================== */
/* TRAFFIC ENGINE — Velocity Operations                                   */
/* ====================================================================== */

function TrafficFlow() {
  // Animated dots traveling along source→middle→conversion paths
  return (
    <svg viewBox="0 0 600 360" preserveAspectRatio="xMidYMid meet" aria-hidden="true">
      {/* Source nodes (left) */}
      {[
        { x: 60, y: 80, label: "TIKTOK" },
        { x: 60, y: 180, label: "META" },
        { x: 60, y: 280, label: "SERP" },
      ].map((s) => (
        <g key={s.label}>
          <rect x={s.x - 36} y={s.y - 14} width="72" height="28" className="room" rx="2" />
          <text x={s.x} y={s.y + 4} textAnchor="middle" className="label-mono active">
            {s.label}
          </text>
        </g>
      ))}

      {/* Middle nodes */}
      {[
        { x: 300, y: 130, label: "LANDING" },
        { x: 300, y: 230, label: "RETARGET" },
      ].map((m) => (
        <g key={m.label}>
          <rect x={m.x - 44} y={m.y - 14} width="88" height="28" className="room active" rx="2" />
          <text x={m.x} y={m.y + 4} textAnchor="middle" className="label-mono active">
            {m.label}
          </text>
        </g>
      ))}

      {/* Conversion node */}
      <g>
        <rect x="476" y="166" width="92" height="28" className="room active" rx="2" />
        <circle cx="522" cy="180" r="14" fill="none" stroke="var(--accent)" strokeOpacity="0.5" />
        <circle cx="522" cy="180" r="4" className="node node-pulse" />
        <text x="522" y="220" textAnchor="middle" className="label-mono active">
          CONVERSION_01
        </text>
      </g>

      {/* Flow links: source → middle */}
      {[
        { d: "M96 80 L256 130" },
        { d: "M96 180 L256 130" },
        { d: "M96 180 L256 230" },
        { d: "M96 280 L256 230" },
      ].map((p, i) => (
        <path key={i} d={p.d} className="link-line live" />
      ))}

      {/* middle → conversion */}
      <path d="M344 130 L476 180" className="link-line live" />
      <path d="M344 230 L476 180" className="link-line live" />

      {/* Tick scale at bottom: sparkline-ish */}
      <g transform="translate(40,310)">
        <line x1="0" y1="20" x2="520" y2="20" stroke="var(--fg-3)" strokeWidth="0.5" opacity="0.4" />
        <polyline
          fill="none"
          stroke="var(--accent)"
          strokeWidth="1.4"
          points="0,18 30,12 60,16 90,8 120,14 150,4 180,10 210,6 240,14 270,2 300,8 330,6 360,4 390,8 420,2 450,6 480,3 510,7 520,5"
        />
        <text x="0" y="36" className="label-mono">T-15M</text>
        <text x="520" y="36" textAnchor="end" className="label-mono active">NOW · +12.4%</text>
      </g>

      {/* Corner marks */}
      <g fill="var(--fg-3)" opacity="0.6">
        <rect x="20" y="20" width="6" height="6" />
        <rect x="574" y="20" width="6" height="6" />
      </g>
    </svg>
  );
}

function TrafficEngine() {
  const now = useUtcClock();
  return (
    <EngineFrame
      kicker="L01 · TRAFFIC ENGINE"
      label="Velocity Ops"
      ref_={fmtUtc(now)}
      readout={
        <>
          <ReadoutCell k="USER_FLOW" v="ACTIVE" delta="●" />
          <ReadoutCell k="CONV_NODE_01" v="STABLE" />
          <ReadoutCell k="INJECTION" v="+12.4%" delta="↑" />
        </>
      }
    >
      <TrafficFlow />
    </EngineFrame>
  );
}

/* ====================================================================== */
/* VISION ENGINE — Intelligence Operations                                */
/* ====================================================================== */

function VisionScene() {
  // Bounding boxes — cycle the active one to scan through all detections
  const boxes = [
    { id: "p", label: "PERSON",  conf: "0.97", x: 60,  y: 60,  w: 160, h: 120 },
    { id: "o", label: "OBJECT",  conf: "0.84", x: 248, y: 92,  w: 100, h: 72  },
    { id: "s", label: "SURFACE", conf: "0.78", x: 92,  y: 206, w: 220, h: 110 },
    { id: "e", label: "EDGE",    conf: "0.62", x: 340, y: 220, w: 80,  h: 60  },
  ];
  const [active, setActive] = useState(0);
  useEffect(() => {
    const id = setInterval(() => setActive((i) => (i + 1) % boxes.length), 2200);
    return () => clearInterval(id);
  }, []);

  const current = boxes[active];

  return (
    <svg viewBox="0 0 600 360" preserveAspectRatio="xMidYMid meet" aria-hidden="true">
      {/* Frame */}
      <rect x="20" y="20" width="420" height="320" className="room" />

      {/* Inner abstract scene: dotted grid */}
      <g opacity="0.18">
        {Array.from({ length: 8 }).map((_, r) =>
          Array.from({ length: 10 }).map((__, c) => (
            <circle key={`${r}-${c}`} cx={50 + c * 40} cy={50 + r * 36} r="1" fill="var(--fg-2)" />
          ))
        )}
      </g>

      {/* Bounding boxes (all 4) */}
      <g>
        {boxes.map((b, i) => {
          const isActive = i === active;
          // Active label sits above the box with a filled chip
          const labelW = (b.label.length + b.conf.length + 3) * 5.6 + 12;
          return (
            <g key={b.id} className={`bbox ${isActive ? "bbox-active" : ""}`}>
              <rect
                x={b.x} y={b.y} width={b.w} height={b.h}
                fill="none"
                stroke={isActive ? "var(--accent)" : "var(--fg-2)"}
                strokeWidth={isActive ? 1.4 : 1}
                strokeDasharray={isActive ? "0" : "3 3"}
                style={{ transition: "stroke 250ms ease, stroke-width 250ms ease" }}
              />
              {isActive ? (
                <>
                  <rect x={b.x} y={b.y - 14} width={labelW} height="14" fill="var(--accent)" />
                  <text x={b.x + 4} y={b.y - 4} className="label-mono"
                        style={{ fill: "#0A0A0A", fontWeight: 600 }}>
                    {b.label} · {b.conf}
                  </text>
                  {/* Crosshair on active */}
                  <g stroke="var(--accent)" strokeWidth="0.8">
                    <line x1={b.x + b.w / 2} y1={b.y - 2} x2={b.x + b.w / 2} y2={b.y + 8} />
                    <line x1={b.x + b.w / 2 - 5} y1={b.y + 3} x2={b.x + b.w / 2 + 5} y2={b.y + 3} />
                  </g>
                </>
              ) : (
                <text x={b.x + 4} y={b.y - 4} className="label-mono">
                  {b.label} · {b.conf}
                </text>
              )}
            </g>
          );
        })}
      </g>

      {/* Pixel scan line — drives off the currently active box */}
      <rect
        key={active /* restart animation when active box changes */}
        x={current.x} y={current.y} width={current.w} height="2"
        fill="var(--accent)" opacity="0.65"
        style={{ transition: "x 250ms ease, width 250ms ease" }}
      >
        <animate attributeName="y"
                 values={`${current.y};${current.y + current.h - 2};${current.y}`}
                 dur="2s" repeatCount="indefinite" />
      </rect>

      {/* Frame meta corners */}
      <g fill="var(--fg-3)" opacity="0.8">
        <text x="26" y="34" className="label-mono">FRAME · 00:00:12:04</text>
        <text x="436" y="34" textAnchor="end" className="label-mono">RGB · 1920×1080</text>
      </g>

      {/* Active detection callout (bottom) */}
      <g transform="translate(20,340)">
        <text x="0" y="0" className="label-mono active" style={{ transition: "all 250ms" }}>
          SCANNING · {current.label} ({active + 1}/{boxes.length})
        </text>
      </g>

      {/* NN sidebar (right) */}
      <g transform="translate(470,40)">
        <text x="0" y="0" className="label-mono active">
          <tspan>MODEL · v4.2</tspan>
          <tspan x="108" textAnchor="end">OUTPUT</tspan>
        </text>
        <text x="0" y="14" className="label-mono">CONV → POOL → FC</text>

        {/* 4 layers of nodes */}
        {[
          { x: 0,  n: 6, label: "INPUT" },
          { x: 36, n: 5, label: "C1" },
          { x: 72, n: 4, label: "C2" },
          { x: 108,n: 3, label: "FC" },
        ].map((layer, li) => (
          <g key={li}>
            {Array.from({ length: layer.n }).map((_, i) => {
              const cy = 50 + i * 30 + (6 - layer.n) * 15;
              // Light up a path that shifts with the active detection
              const litRow = (active + li) % layer.n;
              const isActive = i === litRow && li > 0;
              return (
                <circle key={i} cx={layer.x} cy={cy} r="3.5"
                        fill={isActive ? "var(--accent)" : "none"}
                        stroke={isActive ? "var(--accent)" : "var(--fg-3)"}
                        strokeWidth="1"
                        style={Object.assign(
                          { transition: "fill 250ms ease, stroke 250ms ease" },
                          isActive ? { filter: "drop-shadow(0 0 5px rgba(var(--accent-glow)/.7))" } : null
                        )}
                />
              );
            })}
            <text x={layer.x} y="240" textAnchor="middle" className="label-mono">{layer.label}</text>
          </g>
        ))}

        {/* connections (decorative) */}
        <g stroke="var(--fg-3)" strokeWidth="0.4" opacity="0.5">
          {[40, 70, 100, 130, 160].map((y) => (
            <line key={y} x1="0" y1={y} x2="108" y2={y - 20 + Math.sin(y) * 6} />
          ))}
        </g>
      </g>
    </svg>
  );
}

function VisionEngine() {
  const now = useUtcClock();
  return (
    <EngineFrame
      kicker="L02 · VISION ENGINE"
      label="Intelligence Ops"
      statusText="INFERRING"
      ref_={fmtUtc(now)}
      readout={
        <>
          <ReadoutCell k="CV_MODEL" v="FINE_TUNED_v4.2" />
          <ReadoutCell k="INFERENCE" v="12ms" delta="p99" />
          <ReadoutCell k="ML_ACCURACY" v="99.8%" delta="↑" />
        </>
      }
    >
      <VisionScene />
    </EngineFrame>
  );
}

/* ====================================================================== */
/* TOUCH ENGINE — Edge node database (infrastructure layer)              */
/* ====================================================================== */

function TouchLattice() {
  // 8-col × 5-row lattice — sized to match Traffic/Vision (600×360 viewBox).
  const COLS = 8, ROWS = 5;
  const xs = Array.from({ length: COLS }, (_, i) => 90 + i * 60);
  const ys = Array.from({ length: ROWS }, (_, j) => 76 + j * 52);

  // Pick a few "active" nodes
  const active = new Set(["1:1", "5:0", "6:3", "2:4", "7:2"]);
  const primary = "3:2"; // brightest, center

  const nodes = [];
  ys.forEach((y, r) => xs.forEach((x, c) => {
    const key = `${c}:${r}`;
    nodes.push({ x, y, key, primary: key === primary, active: active.has(key) });
  }));

  // Mesh: connect each node to its right + down neighbors (sparse)
  const links = [];
  for (let r = 0; r < ROWS; r++) {
    for (let c = 0; c < COLS; c++) {
      const a = { x: xs[c], y: ys[r] };
      if (c < COLS - 1) {
        const b = { x: xs[c + 1], y: ys[r] };
        links.push({ a, b, live: (c + r) % 3 === 0 });
      }
      if (r < ROWS - 1 && c % 2 === 0) {
        const b = { x: xs[c], y: ys[r + 1] };
        links.push({ a, b, live: (c + r) % 4 === 0 });
      }
    }
  }

  return (
    <svg viewBox="0 0 600 360" preserveAspectRatio="xMidYMid meet" aria-hidden="true">
      {/* Region labels (top) */}
      <g fill="var(--fg-3)" opacity="0.75">
        <text x="120" y="38" textAnchor="middle" className="label-mono">AMER</text>
        <text x="240" y="38" textAnchor="middle" className="label-mono">EU</text>
        <text x="360" y="38" textAnchor="middle" className="label-mono">MENA</text>
        <text x="480" y="38" textAnchor="middle" className="label-mono">APAC</text>
      </g>

      {/* Region delimiters */}
      <g>
        {[180, 300, 420].map((x, i) => (
          <line key={i} x1={x} y1="50" x2={x} y2="310"
                stroke="var(--line)" strokeWidth="0.5" strokeDasharray="2 4" />
        ))}
      </g>

      {/* Mesh links */}
      <g>
        {links.map((l, i) => (
          <line key={i} x1={l.a.x} y1={l.a.y} x2={l.b.x} y2={l.b.y}
                className={`link-line ${l.live ? "live" : ""}`}
                strokeWidth="0.6" />
        ))}
      </g>

      {/* Nodes */}
      <g>
        {nodes.map((n) => (
          <g key={n.key}>
            {n.primary && (
              <>
                <circle cx={n.x} cy={n.y} r="14" fill="none"
                        stroke="var(--accent)" strokeOpacity="0.5" />
                <circle cx={n.x} cy={n.y} r="22" fill="none"
                        stroke="var(--accent)" strokeOpacity="0.15" />
              </>
            )}
            <circle
              cx={n.x} cy={n.y}
              r={n.primary ? 4.5 : 3}
              fill={n.active || n.primary ? "var(--accent)" : "var(--fg-3)"}
              opacity={n.active || n.primary ? 1 : 0.55}
              className={n.primary ? "node node-pulse" : ""}
              style={n.primary ? { filter: "drop-shadow(0 0 6px rgba(var(--accent-glow)/.7))" } : null}
            />
          </g>
        ))}
      </g>

      {/* Primary node callout */}
      <g>
        <line x1={xs[3]} y1={ys[2] - 20} x2={xs[3]} y2={ys[2] - 6}
              stroke="var(--accent)" strokeWidth="0.6" />
        <text x={xs[3]} y={ys[2] - 26} textAnchor="middle" className="label-mono active">
          PRIMARY · NODE-EU-04
        </text>
      </g>

      {/* Bottom legend */}
      <g transform="translate(30,340)">
        <text x="0" y="0" className="label-mono">● ACTIVE</text>
        <text x="80" y="0" className="label-mono">— SYNC LIVE</text>
        <text x="190" y="0" className="label-mono">·· COLD</text>
        <text x="560" y="0" textAnchor="end" className="label-mono active">UPTIME · 99.99%</text>
      </g>
    </svg>
  );
}

function TouchEngine() {
  const now = useUtcClock();
  return (
    <div className="touch-engine">
      <div className="touch-head">
        <div className="touch-head-left">
          <Eyebrow>L03 · V.I. Infrastructure</Eyebrow>
          <h2 className="touch-title">
            Touch Engine<br />
            <span className="touch-sub">The edge-node database under Traffic &amp; Vision.</span>
          </h2>
        </div>
        <div className="touch-head-right">
          <p className="touch-body">
            The most advanced edge-node database built for V.I. —
            purpose-built for ultra-low-latency lookup, model-weight distribution,
            and real-time inference state. Traffic and Vision both ride on it.
            We license it; we operate it; we never spin it down.
          </p>
          <div className="touch-status mono">
            <span><span className="dot" />V.I. MESH · LIVE</span>
            <span>{fmtUtc(now)}</span>
            <span>BUILD · v7.04-prod</span>
          </div>
        </div>
      </div>

      <div className="touch-canvas">
        <TouchLattice />
      </div>

      <div className="touch-kpis">
        {TOUCH_KPIS.map((k) => (
          <div className="tk-cell" key={k.k}>
            <div className="tk-k mono">{k.k}</div>
            <div className="tk-v">{k.v}</div>
            <div className="tk-note mono">{k.note}</div>
          </div>
        ))}
      </div>
    </div>
  );
}

/* ====================================================================== */
/* TICKER (shared)                                                         */
/* ====================================================================== */

function Ticker() {
  const items = [...TICKER_ITEMS, ...TICKER_ITEMS];
  return (
    <div className="ticker" aria-hidden="true">
      <div className="scroll">
        {items.map((t, i) => (
          <div key={i} className="item">
            <span className="ind" />
            {t}
          </div>
        ))}
      </div>
    </div>
  );
}

Object.assign(window, {
  TrafficEngine, VisionEngine, TouchEngine, Ticker, EngineFrame, useUtcClock,
  TrafficFlow, VisionScene, TouchLattice,
});
