/* global React */
const { useEffect, useRef } = React;

/**
 * GoldVideo — canvas-rendered, infinite loop, abstract premium light lines.
 * Three styles: 'waves' (default elegant), 'lines' (parallel light lines), 'orbit' (circular flow).
 */
function GoldVideo({ style = 'waves', accent = '#c9a84c', dark = false }) {
  const canvasRef = useRef(null);
  const rafRef = useRef(0);
  const startRef = useRef(performance.now());

  useEffect(() => {
    const canvas = canvasRef.current;
    const ctx = canvas.getContext('2d');
    let dpr = Math.min(window.devicePixelRatio || 1, 2);

    const resize = () => {
      const rect = canvas.getBoundingClientRect();
      dpr = Math.min(window.devicePixelRatio || 1, 2);
      canvas.width = rect.width * dpr;
      canvas.height = rect.height * dpr;
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
    };
    resize();
    const ro = new ResizeObserver(resize);
    ro.observe(canvas);

    // Parse accent hex to rgb
    const hexToRgb = (hex) => {
      const h = hex.replace('#', '');
      const n = parseInt(h.length === 3 ? h.split('').map(c => c + c).join('') : h, 16);
      return [(n >> 16) & 255, (n >> 8) & 255, n & 255];
    };
    const [ar, ag, ab] = hexToRgb(accent);
    const accentRgba = (a) => `rgba(${ar},${ag},${ab},${a})`;

    const bg = dark ? '#0a1230' : '#111d4a';

    const draw = () => {
      const t = (performance.now() - startRef.current) / 1000;
      const w = canvas.width / dpr;
      const h = canvas.height / dpr;

      // Background — deep navy with subtle radial vignette
      ctx.fillStyle = bg;
      ctx.fillRect(0, 0, w, h);

      // Soft vignette glow center-left
      const grad = ctx.createRadialGradient(w * 0.35, h * 0.5, 0, w * 0.35, h * 0.5, Math.max(w, h) * 0.7);
      grad.addColorStop(0, accentRgba(0.08));
      grad.addColorStop(0.5, accentRgba(0.02));
      grad.addColorStop(1, 'rgba(0,0,0,0)');
      ctx.fillStyle = grad;
      ctx.fillRect(0, 0, w, h);

      if (style === 'waves') drawWaves(ctx, w, h, t, accentRgba);
      else if (style === 'lines') drawLines(ctx, w, h, t, accentRgba);
      else if (style === 'orbit') drawOrbit(ctx, w, h, t, accentRgba);

      // Subtle grain overlay
      drawGrain(ctx, w, h, t);

      rafRef.current = requestAnimationFrame(draw);
    };

    rafRef.current = requestAnimationFrame(draw);
    return () => {
      cancelAnimationFrame(rafRef.current);
      ro.disconnect();
    };
  }, [style, accent, dark]);

  return (
    <canvas
      ref={canvasRef}
      style={{
        width: '100%',
        height: '100%',
        display: 'block',
      }}
    />
  );
}

/* ---------- WAVES: flowing horizontal sine layers ---------- */
function drawWaves(ctx, w, h, t, accentRgba) {
  const lines = 22;
  const baseY = h * 0.5;

  for (let i = 0; i < lines; i++) {
    const phase = i / lines;
    const offset = (phase - 0.5) * h * 0.85;
    const speed = 0.35 + phase * 0.25;
    const ampBase = 22 + phase * 38;
    const opacity = 0.06 + 0.45 * Math.pow(1 - Math.abs(phase - 0.5) * 2, 2);

    ctx.beginPath();
    ctx.lineWidth = 0.7 + (1 - Math.abs(phase - 0.5) * 2) * 0.8;
    ctx.strokeStyle = accentRgba(opacity);

    const steps = 80;
    for (let s = 0; s <= steps; s++) {
      const x = (s / steps) * w;
      const nx = s / steps;
      const wave1 = Math.sin(nx * 4.5 + t * speed + i * 0.4) * ampBase;
      const wave2 = Math.sin(nx * 2.1 - t * speed * 0.7 + i * 0.2) * (ampBase * 0.4);
      const breath = Math.sin(t * 0.3 + i * 0.6) * 8;
      const y = baseY + offset + wave1 + wave2 + breath;
      if (s === 0) ctx.moveTo(x, y);
      else ctx.lineTo(x, y);
    }
    ctx.stroke();
  }

  // Bright leading line
  ctx.beginPath();
  ctx.lineWidth = 1.4;
  ctx.strokeStyle = accentRgba(0.9);
  const steps = 120;
  for (let s = 0; s <= steps; s++) {
    const nx = s / steps;
    const x = nx * w;
    const y = baseY + Math.sin(nx * 3.2 + t * 0.5) * 36 + Math.sin(nx * 1.4 - t * 0.3) * 14;
    if (s === 0) ctx.moveTo(x, y);
    else ctx.lineTo(x, y);
  }
  ctx.stroke();

  // Glow pass
  ctx.save();
  ctx.filter = 'blur(8px)';
  ctx.beginPath();
  ctx.lineWidth = 3;
  ctx.strokeStyle = accentRgba(0.35);
  for (let s = 0; s <= steps; s++) {
    const nx = s / steps;
    const x = nx * w;
    const y = baseY + Math.sin(nx * 3.2 + t * 0.5) * 36 + Math.sin(nx * 1.4 - t * 0.3) * 14;
    if (s === 0) ctx.moveTo(x, y);
    else ctx.lineTo(x, y);
  }
  ctx.stroke();
  ctx.restore();
}

/* ---------- LINES: parallel diagonal light beams ---------- */
function drawLines(ctx, w, h, t, accentRgba) {
  const count = 14;
  ctx.save();
  ctx.translate(w / 2, h / 2);
  ctx.rotate(-0.18);
  ctx.translate(-w / 2, -h / 2);

  for (let i = 0; i < count; i++) {
    const p = i / count;
    const yBase = p * h * 1.4 - h * 0.2;
    const yWave = Math.sin(t * 0.5 + i * 0.7) * 14;
    const y = yBase + yWave;
    const opacity = 0.12 + Math.sin(t * 0.6 + i * 0.9) * 0.1 + 0.2;

    // Drift across x
    const drift = ((t * 30 + i * 110) % (w + 400)) - 200;

    const grad = ctx.createLinearGradient(drift - 200, y, drift + 200, y);
    grad.addColorStop(0, accentRgba(0));
    grad.addColorStop(0.5, accentRgba(opacity));
    grad.addColorStop(1, accentRgba(0));
    ctx.strokeStyle = grad;
    ctx.lineWidth = 0.8 + Math.sin(t + i) * 0.3 + 0.6;
    ctx.beginPath();
    ctx.moveTo(0, y);
    ctx.lineTo(w, y);
    ctx.stroke();
  }
  ctx.restore();
}

/* ---------- ORBIT: concentric arcs flowing ---------- */
function drawOrbit(ctx, w, h, t, accentRgba) {
  const cx = w * 0.42;
  const cy = h * 0.5;
  const rings = 10;
  const maxR = Math.min(w, h) * 0.55;

  for (let i = 0; i < rings; i++) {
    const p = i / rings;
    const r = maxR * (0.18 + p * 0.85);
    const speed = 0.2 + p * 0.4;
    const dir = i % 2 === 0 ? 1 : -1;
    const angle = t * speed * dir + i * 0.6;
    const arcLen = 0.5 + Math.sin(t * 0.4 + i) * 0.25;

    ctx.beginPath();
    ctx.lineWidth = 0.7 + (1 - p) * 0.7;
    ctx.strokeStyle = accentRgba(0.12 + (1 - p) * 0.35);
    ctx.arc(cx, cy, r, angle, angle + arcLen);
    ctx.stroke();

    // Faint full ring
    ctx.beginPath();
    ctx.lineWidth = 0.4;
    ctx.strokeStyle = accentRgba(0.05);
    ctx.arc(cx, cy, r, 0, Math.PI * 2);
    ctx.stroke();
  }

  // Center node
  ctx.beginPath();
  ctx.fillStyle = accentRgba(0.9);
  ctx.arc(cx, cy, 3, 0, Math.PI * 2);
  ctx.fill();
  ctx.save();
  ctx.filter = 'blur(10px)';
  ctx.beginPath();
  ctx.fillStyle = accentRgba(0.6);
  ctx.arc(cx, cy, 8, 0, Math.PI * 2);
  ctx.fill();
  ctx.restore();
}

/* ---------- Grain ---------- */
let grainCanvas = null;
function drawGrain(ctx, w, h, t) {
  if (!grainCanvas) {
    grainCanvas = document.createElement('canvas');
    grainCanvas.width = 200;
    grainCanvas.height = 200;
    const gctx = grainCanvas.getContext('2d');
    const img = gctx.createImageData(200, 200);
    for (let i = 0; i < img.data.length; i += 4) {
      const v = Math.random() * 255;
      img.data[i] = img.data[i + 1] = img.data[i + 2] = v;
      img.data[i + 3] = 14;
    }
    gctx.putImageData(img, 0, 0);
  }
  ctx.save();
  ctx.globalCompositeOperation = 'overlay';
  ctx.globalAlpha = 0.35;
  const offX = (t * 13) % 200;
  const offY = (t * 7) % 200;
  for (let x = -200; x < w + 200; x += 200) {
    for (let y = -200; y < h + 200; y += 200) {
      ctx.drawImage(grainCanvas, x - offX, y - offY);
    }
  }
  ctx.restore();
}

window.GoldVideo = GoldVideo;
