// hud.jsx — Stark-style HUD overlays: reticles, brackets, telemetry, scanlines.
// Everything here uses ORANGE + white hairlines + neutrals only, no new accents.

// ─── Rotating reticle that locks onto the mark ─────────────────────────────
// Phases:
//   0..2.0s  — spinning concentric rings, "SCANNING"
//   2.0..3.6s — tightens + adds brackets, "LOCKED"
//   3.6..7s  — rings expand outward as mark disperses
//   7..11s   — rotates faster, showing telemetry of agent positions
//   11..13s  — settles into corner frame
function StarkReticle() {
  const t = useTime();

  // Reticle expands as the mark disperses
  const baseR = interpolate(
    [0, 2.0, 3.6, 7.0, 8.5, 11.0],
    [180, 170, 240, 480, 440, 380],
    Easing.easeInOutCubic
  )(t);

  const ringOpacity = interpolate(
    [0, 0.6, 2.0, 3.6, 8.5, 10.8, 11.2],
    [0, 0.5, 0.9, 0.7, 0.5, 0.3, 0.0],
    Easing.easeInOutCubic
  )(t);

  // Locked dead-center for the whole animation.
  const cx = W / 2;
  const cy = H / 2;

  const spin1 = (t * 18) % 360;   // outer slow
  const spin2 = (-t * 32) % 360;  // inner counter
  const spin3 = (t * 60) % 360;   // fast

  if (ringOpacity <= 0.01) return null;

  return (
    <svg width={W} height={H} viewBox={`0 0 ${W} ${H}`}
         style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }}>
      <g transform={`translate(${cx} ${cy})`} opacity={ringOpacity}>
        {/* Outer ring with tick marks */}
        <g transform={`rotate(${spin1})`}>
          <circle r={baseR} fill="none" stroke={ORANGE} strokeWidth="1" opacity="0.6"/>
          {Array.from({ length: 60 }).map((_, i) => {
            const a = (i / 60) * Math.PI * 2;
            const r1 = baseR;
            const r2 = baseR + (i % 5 === 0 ? 14 : 6);
            return (
              <line key={i}
                    x1={Math.cos(a) * r1} y1={Math.sin(a) * r1}
                    x2={Math.cos(a) * r2} y2={Math.sin(a) * r2}
                    stroke={ORANGE} strokeWidth="1"
                    opacity={i % 5 === 0 ? 0.9 : 0.5}/>
            );
          })}
        </g>

        {/* Middle ring — dashed, counter-rotating */}
        <g transform={`rotate(${spin2})`}>
          <circle r={baseR - 26} fill="none" stroke="#ffffff"
                  strokeWidth="1" strokeDasharray="2 10" opacity="0.25"/>
        </g>

        {/* Inner ring — heavier, rotates with fast arc gap */}
        <g transform={`rotate(${spin3})`}>
          <circle r={baseR - 52} fill="none" stroke={ORANGE}
                  strokeWidth="1.5"
                  strokeDasharray={`${(baseR - 52) * 0.4} ${(baseR - 52) * 2}`}
                  opacity="0.7"/>
        </g>

        {/* Crosshair + center dot */}
        <line x1={-baseR - 20} y1="0" x2={-baseR + 30} y2="0"
              stroke={ORANGE} strokeWidth="1" opacity="0.7"/>
        <line x1={baseR - 30} y1="0" x2={baseR + 20} y2="0"
              stroke={ORANGE} strokeWidth="1" opacity="0.7"/>
        <line x1="0" y1={-baseR - 20} x2="0" y2={-baseR + 30}
              stroke={ORANGE} strokeWidth="1" opacity="0.7"/>
        <line x1="0" y1={baseR - 30} x2="0" y2={baseR + 20}
              stroke={ORANGE} strokeWidth="1" opacity="0.7"/>

        {/* Corner brackets, 4 quadrants */}
        {[[-1,-1],[1,-1],[1,1],[-1,1]].map(([sx, sy], i) => {
          const bx = sx * (baseR + 40);
          const by = sy * (baseR + 40);
          const len = 22;
          return (
            <g key={i} transform={`translate(${bx} ${by})`} opacity="0.9">
              <line x1="0" y1="0" x2={-sx * len} y2="0" stroke={ORANGE} strokeWidth="2"/>
              <line x1="0" y1="0" x2="0" y2={-sy * len} stroke={ORANGE} strokeWidth="2"/>
            </g>
          );
        })}
      </g>
    </svg>
  );
}

// ─── Targeting brackets that hug the mark ──────────────────────────────────
// Appear during lockup, tighten as quantize begins, then explode outward.
function LockBrackets() {
  const t = useTime();

  // Size & opacity
  const pad = interpolate(
    [0.4, 1.6, 2.4, 3.6, 4.5],
    [80, 36, 26, 80, 400],
    [Easing.easeOutCubic, Easing.easeInOutCubic, Easing.easeInCubic, Easing.easeInExpo]
  )(t);
  const op = interpolate(
    [0.3, 0.8, 2.2, 3.0, 4.2],
    [0, 1, 1, 0.7, 0],
    Easing.easeInOutCubic
  )(t);

  if (op <= 0.01) return null;

  const cx = W / 2;
  const cy = H / 2;
  const half = MARK_SIZE / 2 + pad;

  const bracketLen = 38;
  const corners = [
    [cx - half, cy - half,  1,  1],
    [cx + half, cy - half, -1,  1],
    [cx + half, cy + half, -1, -1],
    [cx - half, cy + half,  1, -1],
  ];

  return (
    <svg width={W} height={H} viewBox={`0 0 ${W} ${H}`}
         style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }}>
      <g opacity={op}>
        {corners.map(([x, y, dx, dy], i) => (
          <g key={i}>
            <line x1={x} y1={y} x2={x + dx * bracketLen} y2={y}
                  stroke={ORANGE} strokeWidth="2.5" strokeLinecap="square"/>
            <line x1={x} y1={y} x2={x} y2={y + dy * bracketLen}
                  stroke={ORANGE} strokeWidth="2.5" strokeLinecap="square"/>
            {/* tiny inner tick */}
            <rect x={x + dx * 6 - 2} y={y + dy * 6 - 2} width="4" height="4" fill={ORANGE}/>
          </g>
        ))}
      </g>
    </svg>
  );
}

// ─── Scanline sweep (reveals blueprint) ────────────────────────────────────
// A thin orange horizontal scanline travels top→bottom once during quantize.
function ScanlineSweep() {
  const t = useTime();
  const p = smoothstep(1.4, 3.2, t);
  if (p <= 0.001 || p >= 1) return null;

  const y = p * H;
  return (
    <svg width={W} height={H} viewBox={`0 0 ${W} ${H}`}
         style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }}>
      <defs>
        <linearGradient id="scan" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0" stopColor={ORANGE} stopOpacity="0"/>
          <stop offset="0.45" stopColor={ORANGE} stopOpacity="0.25"/>
          <stop offset="0.5" stopColor={ORANGE} stopOpacity="1"/>
          <stop offset="0.55" stopColor={ORANGE} stopOpacity="0.25"/>
          <stop offset="1" stopColor={ORANGE} stopOpacity="0"/>
        </linearGradient>
      </defs>
      <rect x="0" y={y - 60} width={W} height="120" fill="url(#scan)"/>
      <line x1="0" y1={y} x2={W} y2={y} stroke={ORANGE} strokeWidth="1" opacity="0.9"/>
    </svg>
  );
}

// ─── Telemetry: streaming hex/decimal numbers in corners ───────────────────
function Telemetry() {
  const t = useTime();
  const op = interpolate(
    [0, 0.6, 1.0, 10.8, 11.4],
    [0, 0, 0.75, 0.75, 0],
    Easing.easeInOutCubic
  )(t);
  if (op <= 0.01) return null;

  // Stable-per-second but flickering values
  const sec = Math.floor(t * 8) / 8;
  const rng = makeRng(Math.floor(sec * 1000) + 1);
  const hex = () => rng().toString(16).slice(2, 8).toUpperCase().padStart(6, '0');
  const dec = (n) => Math.floor(rng() * n).toString().padStart(4, '0');

  // Agent count ramps during scatter
  const agents = Math.floor(interpolate(
    [0, TL.quantizeStart, TL.scatterStart, TL.floodStart, TL.floodEnd, TL.holdStart],
    [1, 1, 284, 820, 1640, 1640],
    Easing.easeInOutCubic
  )(t));

  const labelStyle = {
    fontFamily: '"JetBrains Mono", ui-monospace, monospace',
    fontSize: 12,
    letterSpacing: '0.2em',
    color: INK_300,
    textTransform: 'uppercase',
    lineHeight: 1.6,
    fontWeight: 500,
    opacity: op,
  };
  const valueStyle = { ...labelStyle, color: ORANGE, opacity: op * 0.95 };

  return (
    <>
      {/* Bottom-left: system telemetry */}
      <div style={{ position: 'absolute', left: 64, bottom: 64, ...labelStyle }}>
        <div>SYS · <span style={{ color: ORANGE }}>FNX-{hex().slice(0,4)}</span></div>
        <div>HASH · {hex()}</div>
        <div>NODES · <span style={{ color: ORANGE }}>{agents.toString().padStart(4, '0')}</span> / 1640</div>
        <div>P95 · {dec(500)}MS</div>
      </div>

      {/* Bottom-right: coordinates */}
      <div style={{ position: 'absolute', right: 64, bottom: 64, textAlign: 'right', ...labelStyle }}>
        <div>LAT  {(rng() * 180 - 90).toFixed(4)}</div>
        <div>LON  {(rng() * 360 - 180).toFixed(4)}</div>
        <div>T+ {t.toFixed(3).padStart(7, '0')}</div>
      </div>
    </>
  );
}

// ─── Boot banner → status line → outcome banner ────────────────────────────
function StatusBanner() {
  const t = useTime();

  // Top-center status that morphs with phase.
  let label;
  if (t < TL.introEnd) label = 'FOUNDRY NX · SYSTEM ONLINE';
  else if (t < TL.quantizeEnd) label = 'TARGET ACQUIRED · DECOMPOSING MARK';
  else if (t < TL.floodStart) label = 'DEPLOYING AGENT SWARM';
  else if (t < TL.resolveStart) label = 'AGENTS ACTIVE · 1,640 NODES';
  else if (t < TL.holdStart) label = 'CONVERGING · LOCK SEQUENCE';
  else label = 'FOUNDRY NX · APPLIED AI';

  // Small "flicker in" whenever label changes — use localTime within each phase.
  const phaseStart =
    t < TL.introEnd ? 0 :
    t < TL.quantizeEnd ? TL.introEnd :
    t < TL.floodStart ? TL.quantizeEnd :
    t < TL.resolveStart ? TL.floodStart :
    t < TL.holdStart ? TL.resolveStart :
    TL.holdStart;
  const localT = t - phaseStart;
  const inOp = clamp(localT / 0.35, 0, 1);

  return (
    <div style={{
      position: 'absolute',
      top: 64, left: 0, right: 0,
      textAlign: 'center',
      opacity: inOp,
      fontFamily: '"JetBrains Mono", ui-monospace, monospace',
      fontSize: 14,
      letterSpacing: '0.32em',
      color: INK_300,
      textTransform: 'uppercase',
      fontWeight: 500,
    }}>
      <span style={{
        display: 'inline-block',
        width: 8, height: 8,
        background: ORANGE,
        marginRight: 14,
        verticalAlign: 'middle',
        opacity: 0.5 + 0.5 * Math.sin(t * 6),
      }}/>
      {label}
    </div>
  );
}

// ─── Blueprint construction lines overlaid on the mark during lockup ───────
// Thin white/orange hairlines measuring the triangle — very Stark blueprint.
function Blueprint() {
  const t = useTime();
  const op = interpolate(
    [1.2, 1.8, 2.6, 3.2],
    [0, 0.8, 0.7, 0],
    Easing.easeInOutCubic
  )(t);
  if (op <= 0.01) return null;

  const cx = W / 2;
  const cy = H / 2 - 170;
  const s = MARK_SIZE / 200;

  // Triangle vertex positions in canvas space
  const v1 = { x: cx + (100 - 100) * s, y: cy + (20 - 100) * s };   // top
  const v2 = { x: cx + (182 - 100) * s, y: cy + (160 - 100) * s };  // bottom-right
  const v3 = { x: cx + (18 - 100) * s, y: cy + (160 - 100) * s };   // bottom-left

  return (
    <svg width={W} height={H} viewBox={`0 0 ${W} ${H}`}
         style={{ position: 'absolute', inset: 0, pointerEvents: 'none', opacity: op }}>
      {/* Extended construction lines */}
      <line x1={v1.x} y1={v1.y - 80} x2={v1.x} y2={v2.y + 80}
            stroke={ORANGE} strokeWidth="1" strokeDasharray="2 6" opacity="0.6"/>
      <line x1={v3.x - 80} y1={v2.y} x2={v2.x + 80} y2={v2.y}
            stroke={ORANGE} strokeWidth="1" strokeDasharray="2 6" opacity="0.6"/>

      {/* Vertex markers */}
      {[v1, v2, v3].map((v, i) => (
        <g key={i}>
          <circle cx={v.x} cy={v.y} r="6" fill="none" stroke={ORANGE} strokeWidth="1.5"/>
          <circle cx={v.x} cy={v.y} r="2" fill={ORANGE}/>
        </g>
      ))}

      {/* Angle arc at apex */}
      <path d={`M ${v1.x - 22} ${v1.y + 30} A 36 36 0 0 0 ${v1.x + 22} ${v1.y + 30}`}
            fill="none" stroke="#ffffff" strokeWidth="1" opacity="0.45"/>

      {/* Dimension labels */}
      <text x={v1.x + 12} y={v1.y + 44}
            fontFamily='"JetBrains Mono", monospace' fontSize="11"
            letterSpacing="0.12em" fill="#ffffff" opacity="0.55">60°</text>
      <text x={(v2.x + v3.x)/2} y={v2.y + 28}
            fontFamily='"JetBrains Mono", monospace' fontSize="11"
            letterSpacing="0.12em" fill={ORANGE} opacity="0.75"
            textAnchor="middle">Δ · 164</text>
    </svg>
  );
}

// ─── Camera: subtle push-in/pull-back via transform on a wrapper ───────────
// Returns a { scale, tx, ty } object given time. Applied to the Video root.
function cameraTransform(t) {
  // Slow push-in during boot (0→2), hold, push-in further during quantize (2→3.6),
  // pull back to reveal swarm (3.6→7), slowly push back in during resolve (8.5→11), hold.
  const scale = interpolate(
    [0,    2.0,  3.6,  5.5,  8.5,  11.0, 13.0],
    [1.00, 1.06, 1.14, 0.96, 0.98, 1.04, 1.03],
    Easing.easeInOutCubic
  )(t);
  const tx = interpolate(
    [0, 6.0, 8.5, 11.0, 13.0],
    [0, 10, -8,  0,    0],
    Easing.easeInOutSine
  )(t);
  const ty = interpolate(
    [0,   2.0, 3.6, 11.0],
    [-6, -10, -18, 0],
    Easing.easeInOutCubic
  )(t);
  return { scale, tx, ty };
}

Object.assign(window, {
  StarkReticle, LockBrackets, ScanlineSweep, Telemetry, StatusBanner, Blueprint,
  cameraTransform,
});
