/* global React */
// ScrollVideoBackground — canvas frame-scrubber tied to scrollY.
// Mirrors AIAS architecture; preloads numbered frames and draws on RAF.
const { useEffect: useEffectSVB, useRef: useRefSVB } = React;

const FRAME_COUNT = 48; // we ship 48 frames (lightweight); brief calls for 240
const FRAME_PATH = (i) => `hero-frames/frame_${String(i).padStart(4, "0")}.jpg`;

const ScrollVideoBackground = () => {
  const canvasRef = useRefSVB(null);
  const imagesRef = useRefSVB([]);
  const lastDrawnRef = useRefSVB(-1);
  const loadedRef = useRefSVB(new Array(FRAME_COUNT).fill(false));

  useEffectSVB(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext("2d");
    const dpr = Math.min(window.devicePixelRatio || 1, 2);

    const sizeCanvas = () => {
      canvas.width = window.innerWidth * dpr;
      canvas.height = window.innerHeight * dpr;
    };
    sizeCanvas();
    window.addEventListener("resize", sizeCanvas);

    for (let i = 0; i < FRAME_COUNT; i++) {
      const img = new Image();
      img.src = FRAME_PATH(i + 1);
      img.onload = () => {
        loadedRef.current[i] = true;
        if (i === 0) draw(0);
      };
      imagesRef.current[i] = img;
    }

    const reduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches;

    const findNearestLoaded = (target) => {
      for (let off = 0; off < FRAME_COUNT; off++) {
        const lo = Math.max(0, target - off);
        const hi = Math.min(FRAME_COUNT - 1, target + off);
        if (loadedRef.current[lo]) return lo;
        if (loadedRef.current[hi]) return hi;
      }
      return 0;
    };

    const draw = (frame) => {
      const idx = findNearestLoaded(frame);
      if (idx === lastDrawnRef.current) return;
      const img = imagesRef.current[idx];
      if (!img || !img.naturalWidth) return;
      const { width, height } = canvas;
      const r = Math.max(width / img.naturalWidth, height / img.naturalHeight);
      const w = img.naturalWidth * r;
      const h = img.naturalHeight * r;
      ctx.clearRect(0, 0, width, height);
      ctx.drawImage(img, (width - w) / 2, (height - h) / 2, w, h);
      lastDrawnRef.current = idx;
    };

    let raf = 0;
    const tick = () => {
      if (!reduced) {
        const scrollMax = document.documentElement.scrollHeight - window.innerHeight;
        const progress = scrollMax > 0 ? Math.max(0, Math.min(1, window.scrollY / scrollMax)) : 0;
        const target = Math.round(progress * (FRAME_COUNT - 1));
        draw(target);
      }
      raf = requestAnimationFrame(tick);
    };
    tick();

    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener("resize", sizeCanvas);
    };
  }, []);

  return (
    <canvas
      ref={canvasRef}
      className="scroll-video-bg"
      aria-hidden="true"
    />
  );
};

window.ScrollVideoBackground = ScrollVideoBackground;
