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

/* ============================================================
   Hero — three background variants
   variant: 'topo' | 'particles' | 'geometry'
   ============================================================ */

function HeroBg({ variant }) {
  if (variant === 'particles') return <ParticleField />;
  if (variant === 'geometry') return <GeometryDrift />;
  return <TopographicLines />;
}

/* --- Variant 1: Topographic contour lines that slowly drift --- */
function TopographicLines() {
  const ref = useRef(null);
  useEffect(() => {
    const canvas = ref.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    let raf;
    let t = 0;
    const dpr = Math.min(window.devicePixelRatio || 1, 2);

    const resize = () => {
      canvas.width = canvas.offsetWidth * dpr;
      canvas.height = canvas.offsetHeight * dpr;
    };
    resize();
    window.addEventListener('resize', resize);

    const draw = () => {
      const w = canvas.width, h = canvas.height;
      ctx.clearRect(0, 0, w, h);

      const accent = getComputedStyle(document.documentElement).getPropertyValue('--accent').trim() || '#C8A258';
      const bone = getComputedStyle(document.documentElement).getPropertyValue('--bone').trim() || '#F4F1EA';

      const step = 38 * dpr;
      const cols = Math.ceil(w / step) + 2;
      const rows = Math.ceil(h / step) + 2;

      // Build height map (perlin-ish via sin combos)
      const noise = (x, y) =>
        Math.sin(x * 0.012 + t * 0.0006) * 0.6 +
        Math.cos(y * 0.014 - t * 0.0004) * 0.5 +
        Math.sin((x + y) * 0.008 + t * 0.0008) * 0.4;

      // Draw concentric contour lines
      const levels = 14;
      for (let lvl = 0; lvl < levels; lvl++) {
        const threshold = -1.2 + (lvl * 2.4) / levels;
        const isAccent = lvl === 6 || lvl === 9;
        ctx.strokeStyle = isAccent
          ? `${accent}` + Math.floor((isAccent ? 0.55 : 0.16) * 255).toString(16).padStart(2, '0')
          : `${bone}` + '14';
        ctx.lineWidth = isAccent ? 1.4 * dpr : 0.8 * dpr;
        ctx.beginPath();

        for (let row = 0; row < rows; row++) {
          for (let col = 0; col < cols; col++) {
            const x0 = col * step, y0 = row * step;
            const x1 = x0 + step, y1 = y0 + step;
            const v00 = noise(x0, y0) - threshold;
            const v10 = noise(x1, y0) - threshold;
            const v11 = noise(x1, y1) - threshold;
            const v01 = noise(x0, y1) - threshold;

            // Marching squares lite: just connect midpoints when sign changes
            const seg = (a, b, va, vb) => {
              if ((va > 0) !== (vb > 0)) {
                const f = va / (va - vb);
                return [a[0] + (b[0] - a[0]) * f, a[1] + (b[1] - a[1]) * f];
              }
              return null;
            };
            const pts = [];
            const t1 = seg([x0, y0], [x1, y0], v00, v10); if (t1) pts.push(t1);
            const t2 = seg([x1, y0], [x1, y1], v10, v11); if (t2) pts.push(t2);
            const t3 = seg([x1, y1], [x0, y1], v11, v01); if (t3) pts.push(t3);
            const t4 = seg([x0, y1], [x0, y0], v01, v00); if (t4) pts.push(t4);

            if (pts.length >= 2) {
              ctx.moveTo(pts[0][0], pts[0][1]);
              ctx.lineTo(pts[1][0], pts[1][1]);
            }
          }
        }
        ctx.stroke();
      }

      t += 16;
      raf = requestAnimationFrame(draw);
    };
    draw();

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

  return <canvas ref={ref} className="hero__canvas" />;
}

/* --- Variant 2: Particle field that coalesces into a shield on scroll --- */
function ParticleField() {
  const ref = useRef(null);
  useEffect(() => {
    const canvas = ref.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    let raf;
    const dpr = Math.min(window.devicePixelRatio || 1, 2);

    const resize = () => {
      canvas.width = canvas.offsetWidth * dpr;
      canvas.height = canvas.offsetHeight * dpr;
    };
    resize();
    window.addEventListener('resize', resize);

    // Build target shield outline (in normalized -1..1 coords)
    const targets = [];
    const N = 320;
    for (let i = 0; i < N; i++) {
      // Shield: top arc + bottom point
      const tt = i / N;
      let x, y;
      if (tt < 0.6) {
        // arc top
        const a = -Math.PI + (tt / 0.6) * Math.PI;
        x = Math.cos(a) * 0.55;
        y = Math.sin(a) * 0.55 - 0.1;
      } else {
        // sides converging to point
        const k = (tt - 0.6) / 0.4;
        const side = i % 2 === 0 ? 1 : -1;
        x = side * 0.55 * (1 - k);
        y = -0.1 + k * 0.95;
      }
      targets.push({ tx: x, ty: y });
    }

    const parts = targets.map(t => ({
      ...t,
      x: (Math.random() * 2 - 1),
      y: (Math.random() * 2 - 1),
      vx: 0, vy: 0,
    }));

    let scrollProg = 0;
    const onScroll = () => {
      const h = window.innerHeight;
      scrollProg = Math.max(0, Math.min(1, window.scrollY / (h * 0.8)));
    };
    window.addEventListener('scroll', onScroll, { passive: true });

    const draw = () => {
      const w = canvas.width, h = canvas.height;
      ctx.clearRect(0, 0, w, h);
      const cx = w / 2, cy = h / 2;
      const scale = Math.min(w, h) * 0.42;

      const accent = getComputedStyle(document.documentElement).getPropertyValue('--accent').trim() || '#C8A258';
      const bone = getComputedStyle(document.documentElement).getPropertyValue('--bone').trim() || '#F4F1EA';

      // Connections
      ctx.strokeStyle = `${bone}10`;
      ctx.lineWidth = 0.6 * dpr;
      for (let i = 0; i < parts.length; i++) {
        const p = parts[i];
        // ease toward target based on scrollProg
        const k = 0.04 + scrollProg * 0.16;
        p.vx = p.vx * 0.86 + (p.tx - p.x) * k;
        p.vy = p.vy * 0.86 + (p.ty - p.y) * k;
        // wander when low scroll
        const wander = (1 - scrollProg) * 0.0006;
        p.vx += (Math.random() - 0.5) * wander;
        p.vy += (Math.random() - 0.5) * wander;
        p.x += p.vx; p.y += p.vy;
      }
      // Draw lines between nearby points (more, as scroll progresses)
      for (let i = 0; i < parts.length; i += 2) {
        for (let j = i + 1; j < Math.min(parts.length, i + 8); j++) {
          const a = parts[i], b = parts[j];
          const dx = a.x - b.x, dy = a.y - b.y;
          const d2 = dx * dx + dy * dy;
          if (d2 < 0.05) {
            ctx.globalAlpha = (0.05 + scrollProg * 0.25) * (1 - d2 / 0.05);
            ctx.beginPath();
            ctx.moveTo(cx + a.x * scale, cy + a.y * scale);
            ctx.lineTo(cx + b.x * scale, cy + b.y * scale);
            ctx.stroke();
          }
        }
      }
      ctx.globalAlpha = 1;

      // Particles
      for (const p of parts) {
        const isAccent = Math.random() < 0.05;
        ctx.fillStyle = isAccent ? accent : bone;
        ctx.globalAlpha = 0.35 + scrollProg * 0.5;
        ctx.beginPath();
        ctx.arc(cx + p.x * scale, cy + p.y * scale, 1.4 * dpr, 0, Math.PI * 2);
        ctx.fill();
      }
      ctx.globalAlpha = 1;

      raf = requestAnimationFrame(draw);
    };
    draw();

    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener('resize', resize);
      window.removeEventListener('scroll', onScroll);
    };
  }, []);
  return <canvas ref={ref} className="hero__canvas" />;
}

/* --- Variant 3: Slow 3D-ish geometry drift (rotating column lines) --- */
function GeometryDrift() {
  const ref = useRef(null);
  useEffect(() => {
    const canvas = ref.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    let raf, t = 0;
    const dpr = Math.min(window.devicePixelRatio || 1, 2);
    const resize = () => {
      canvas.width = canvas.offsetWidth * dpr;
      canvas.height = canvas.offsetHeight * dpr;
    };
    resize();
    window.addEventListener('resize', resize);

    let scrollProg = 0;
    const onScroll = () => {
      scrollProg = Math.max(0, Math.min(1, window.scrollY / window.innerHeight));
    };
    window.addEventListener('scroll', onScroll, { passive: true });

    const draw = () => {
      const w = canvas.width, h = canvas.height;
      ctx.clearRect(0, 0, w, h);
      const cx = w / 2, cy = h / 2 + h * 0.05;

      const accent = getComputedStyle(document.documentElement).getPropertyValue('--accent').trim() || '#C8A258';
      const bone = getComputedStyle(document.documentElement).getPropertyValue('--bone').trim() || '#F4F1EA';

      // Series of nested arches
      const arches = 9;
      for (let i = 0; i < arches; i++) {
        const k = i / arches;
        const radius = (Math.min(w, h) * 0.18) + i * 30 * dpr + scrollProg * 80 * dpr;
        const rotate = t * 0.0001 * (1 + k * 0.5);
        const isAccent = i === 3;
        ctx.strokeStyle = isAccent
          ? `${accent}${Math.floor(0.55 * 255).toString(16).padStart(2, '0')}`
          : `${bone}${Math.floor((0.18 - k * 0.12) * 255).toString(16).padStart(2, '0')}`;
        ctx.lineWidth = (isAccent ? 1.5 : 0.8) * dpr;

        // Draw arch (top half)
        ctx.beginPath();
        for (let a = -Math.PI; a <= 0; a += Math.PI / 80) {
          const ar = a + Math.sin(rotate + i * 0.3) * 0.05;
          const x = cx + Math.cos(ar) * radius;
          const y = cy + Math.sin(ar) * radius;
          if (a === -Math.PI) ctx.moveTo(x, y);
          else ctx.lineTo(x, y);
        }
        ctx.stroke();

        // vertical columns from arch ends
        ctx.beginPath();
        const x1 = cx - radius, x2 = cx + radius;
        ctx.moveTo(x1, cy);
        ctx.lineTo(x1, h);
        ctx.moveTo(x2, cy);
        ctx.lineTo(x2, h);
        ctx.stroke();
      }

      // Faint horizon
      ctx.strokeStyle = `${bone}24`;
      ctx.lineWidth = 1 * dpr;
      ctx.beginPath();
      ctx.moveTo(0, cy);
      ctx.lineTo(w, cy);
      ctx.stroke();

      t += 16;
      raf = requestAnimationFrame(draw);
    };
    draw();

    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener('resize', resize);
      window.removeEventListener('scroll', onScroll);
    };
  }, []);
  return <canvas ref={ref} className="hero__canvas" />;
}

window.HeroBg = HeroBg;
