/* =========================================================
   NETRA AI — simulated camera feed
   Procedurally renders a moving scene with detected "people" as bounding boxes.
   ========================================================= */

const SimFeed = ({ scene = "lobby", seed = 1, alert = null, showBoxes = true, tint = null }) => {
  const ref = React.useRef(null);
  const rafRef = React.useRef(0);
  const [tick, setTick] = React.useState(0);
  const startRef = React.useRef(performance.now());

  // pseudo-random determined by seed
  const rand = (i) => {
    const x = Math.sin(seed * 9999 + i * 31.7) * 10000;
    return x - Math.floor(x);
  };

  // entities defined per scene
  const ents = React.useMemo(() => {
    const pool = [];
    const count = scene === "lobby" ? 4 : scene === "perimeter" ? 2 : scene === "server" ? 1 : scene === "dock" ? 2 : 3;
    for (let i = 0; i < count; i++) {
      pool.push({
        i,
        baseX: 0.15 + rand(i) * 0.7,
        baseY: 0.55 + rand(i + 7) * 0.25,
        amp: 0.06 + rand(i + 13) * 0.18,
        sp: 0.4 + rand(i + 19) * 0.9,
        size: 0.07 + rand(i + 3) * 0.05,
        phase: rand(i + 23) * Math.PI * 2,
        type: rand(i + 33) < 0.2 ? "obj" : "person",
      });
    }
    return pool;
  }, [seed, scene]);

  React.useEffect(() => {
    const loop = () => {
      setTick(t => t + 1);
      rafRef.current = requestAnimationFrame(loop);
    };
    rafRef.current = requestAnimationFrame(loop);
    return () => cancelAnimationFrame(rafRef.current);
  }, []);

  React.useEffect(() => {
    const canvas = ref.current;
    if (!canvas) return;
    const ctx = canvas.getContext("2d");
    const W = canvas.width = canvas.clientWidth * window.devicePixelRatio;
    const H = canvas.height = canvas.clientHeight * window.devicePixelRatio;
    const time = (performance.now() - startRef.current) / 1000;

    // background gradient — different per scene
    const bgs = {
      lobby:     ["#0b1424", "#0a1e2e"],
      perimeter: ["#0a1118", "#15110a"],
      server:    ["#0b0d18", "#0d1a22"],
      dock:      ["#161208", "#1a1208"],
      lab:       ["#0a1820", "#0a1018"],
      common:    ["#0d1820", "#0a1418"],
      roof:      ["#0b1018", "#161608"],
    };
    const [c1, c2] = bgs[scene] || bgs.lobby;
    const g = ctx.createLinearGradient(0, 0, 0, H);
    g.addColorStop(0, c1); g.addColorStop(1, c2);
    ctx.fillStyle = g; ctx.fillRect(0, 0, W, H);

    const horizon = H * 0.45;

    // far structures — abstract boxes / silhouettes
    ctx.fillStyle = "rgba(255,255,255,0.025)";
    for (let i = 0; i < 6; i++) {
      const x = (i / 6) * W + rand(i + 99) * 30;
      const bw = 80 + rand(i + 101) * 60;
      const bh = 60 + rand(i + 102) * 60;
      ctx.fillRect(x, horizon - bh + 6, bw, bh);
    }

    // edge vignette
    const vg = ctx.createRadialGradient(W/2, H/2, Math.min(W,H)*0.3, W/2, H/2, Math.max(W,H)*0.7);
    vg.addColorStop(0, "rgba(0,0,0,0)");
    vg.addColorStop(1, "rgba(0,0,0,0.5)");
    ctx.fillStyle = vg; ctx.fillRect(0, 0, W, H);

    // (removed) film-grain strip — putImageData was overwriting alpha
    // and showing as a flickering black band across each feed.

    // tint overlay
    if (tint) {
      ctx.fillStyle = tint;
      ctx.fillRect(0, 0, W, H);
    }

    return undefined;
  }, [tick, scene, tint]);

  // entity positions for bounding boxes (compute in render so they animate)
  const time = (performance.now() - startRef.current) / 1000;
  const positions = ents.map(e => {
    const x = e.baseX + Math.cos(time * e.sp + e.phase) * e.amp;
    const y = e.baseY + Math.sin(time * e.sp * 0.7 + e.phase) * (e.amp * 0.3);
    return { ...e, x, y };
  });

  return (
    <div style={{position: "absolute", inset: 0}}>
      <canvas ref={ref} style={{width: "100%", height: "100%", display: "block"}} />
      {showBoxes && positions.map((p, i) => {
        const isTarget = alert && i === 0;
        const cls = isTarget ? (alert === "crit" ? "crit" : "warn") : "";
        const w = p.size * 100, h = w * 1.6;
        return (
          <div key={i} className={`bbox ${cls}`}
               data-label={p.type === "obj" ? "OBJECT 0.79" : isTarget ? (alert === "crit" ? "UNKNOWN 0.92" : "PERSON 0.88") : `PERSON ${(0.7 + (i*0.05)).toFixed(2)}`}
               style={{
                 left: `${p.x * 100 - w/2}%`,
                 top:  `${p.y * 100 - h/2}%`,
                 width: `${w}%`,
                 height: `${h}%`,
               }} />
        );
      })}
    </div>
  );
};

window.SimFeed = SimFeed;
