// WavesBackground — Interactive wave animation background
// Adapted from TypeScript for CDN React

const { useEffect, useRef } = React;

function WavesBackground({
  className = "",
  strokeColor = "rgba(6, 182, 212, 0.25)",
  backgroundColor = "transparent",
  pointerSize = 0.5
}) {
  const containerRef = useRef(null);
  const svgRef = useRef(null);
  const mouseRef = useRef({
    x: -10,
    y: 0,
    lx: 0,
    ly: 0,
    sx: 0,
    sy: 0,
    v: 0,
    vs: 0,
    a: 0,
    set: false,
  });
  const pathsRef = useRef([]);
  const linesRef = useRef([]);
  const noiseRef = useRef(null);
  const rafRef = useRef(null);
  const boundingRef = useRef(null);

  useEffect(() => {
    if (!containerRef.current || !svgRef.current) return;

    // Initialize noise generator
    noiseRef.current = window.createNoise2D();

    // Set SVG size
    const setSize = () => {
      if (!containerRef.current || !svgRef.current) return;
      boundingRef.current = containerRef.current.getBoundingClientRect();
      const { width, height } = boundingRef.current;
      svgRef.current.style.width = `${width}px`;
      svgRef.current.style.height = `${height}px`;
    };

    // Setup lines
    const setLines = () => {
      if (!svgRef.current || !boundingRef.current) return;

      const { width, height } = boundingRef.current;
      linesRef.current = [];

      // Clear existing paths
      pathsRef.current.forEach(path => path.remove());
      pathsRef.current = [];

      const xGap = 14;
      const yGap = 8;

      const oWidth = width + 200;
      const oHeight = height + 30;

      const totalLines = Math.ceil(oWidth / xGap);
      const totalPoints = Math.ceil(oHeight / yGap);

      const xStart = (width - xGap * totalLines) / 2;
      const yStart = (height - yGap * totalPoints) / 2;

      // Create vertical lines
      for (let i = 0; i < totalLines; i++) {
        const points = [];

        for (let j = 0; j < totalPoints; j++) {
          const point = {
            x: xStart + xGap * i,
            y: yStart + yGap * j,
            wave: { x: 0, y: 0 },
            cursor: { x: 0, y: 0, vx: 0, vy: 0 },
          };
          points.push(point);
        }

        // Create SVG path
        const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
        path.setAttribute('fill', 'none');
        path.setAttribute('stroke', strokeColor);
        path.setAttribute('stroke-width', '1.5');

        svgRef.current.appendChild(path);
        pathsRef.current.push(path);
        linesRef.current.push(points);
      }
    };

    // Mouse handler
    const onMouseMove = (e) => {
      updateMousePosition(e.pageX, e.pageY);
    };

    // Touch handler
    const onTouchMove = (e) => {
      e.preventDefault();
      const touch = e.touches[0];
      updateMousePosition(touch.clientX, touch.clientY);
    };

    // Update mouse position
    const updateMousePosition = (x, y) => {
      if (!boundingRef.current) return;

      const mouse = mouseRef.current;
      mouse.x = x - boundingRef.current.left;
      mouse.y = y - boundingRef.current.top + window.scrollY;

      if (!mouse.set) {
        mouse.sx = mouse.x;
        mouse.sy = mouse.y;
        mouse.lx = mouse.x;
        mouse.ly = mouse.y;
        mouse.set = true;
      }
    };

    // Move points
    const movePoints = (time) => {
      const lines = linesRef.current;
      const mouse = mouseRef.current;
      const noise = noiseRef.current;

      if (!noise) return;

      lines.forEach((points) => {
        points.forEach((p) => {
          // Wave movement - more visible and dynamic
          const move = noise(
            (p.x + time * 0.015) * 0.004,
            (p.y + time * 0.008) * 0.003
          ) * 12;

          p.wave.x = Math.cos(move) * 18;
          p.wave.y = Math.sin(move) * 10;

          // Mouse effect
          const dx = p.x - mouse.sx;
          const dy = p.y - mouse.sy;
          const d = Math.hypot(dx, dy);
          const l = Math.max(175, mouse.vs);

          if (d < l) {
            const s = 1 - d / l;
            const f = Math.cos(d * 0.001) * s;

            p.cursor.vx += Math.cos(mouse.a) * f * l * mouse.vs * 0.00035;
            p.cursor.vy += Math.sin(mouse.a) * f * l * mouse.vs * 0.00035;
          }

          p.cursor.vx += (0 - p.cursor.x) * 0.01;
          p.cursor.vy += (0 - p.cursor.y) * 0.01;

          p.cursor.vx *= 0.95;
          p.cursor.vy *= 0.95;

          p.cursor.x += p.cursor.vx;
          p.cursor.y += p.cursor.vy;

          p.cursor.x = Math.min(50, Math.max(-50, p.cursor.x));
          p.cursor.y = Math.min(50, Math.max(-50, p.cursor.y));
        });
      });
    };

    // Get moved point coordinates
    const moved = (point, withCursorForce = true) => {
      return {
        x: point.x + point.wave.x + (withCursorForce ? point.cursor.x : 0),
        y: point.y + point.wave.y + (withCursorForce ? point.cursor.y : 0),
      };
    };

    // Draw lines
    const drawLines = () => {
      const lines = linesRef.current;
      const paths = pathsRef.current;

      lines.forEach((points, lIndex) => {
        if (points.length < 2 || !paths[lIndex]) return;

        const firstPoint = moved(points[0], false);
        let d = `M ${firstPoint.x} ${firstPoint.y}`;

        for (let i = 1; i < points.length; i++) {
          const current = moved(points[i]);
          d += `L ${current.x} ${current.y}`;
        }

        paths[lIndex].setAttribute('d', d);
      });
    };

    // Animation loop
    const tick = (time) => {
      const mouse = mouseRef.current;

      // Smooth mouse movement
      mouse.sx += (mouse.x - mouse.sx) * 0.1;
      mouse.sy += (mouse.y - mouse.sy) * 0.1;

      // Mouse velocity
      const dx = mouse.x - mouse.lx;
      const dy = mouse.y - mouse.ly;
      const d = Math.hypot(dx, dy);

      mouse.v = d;
      mouse.vs += (d - mouse.vs) * 0.1;
      mouse.vs = Math.min(100, mouse.vs);

      mouse.lx = mouse.x;
      mouse.ly = mouse.y;

      mouse.a = Math.atan2(dy, dx);

      movePoints(time);
      drawLines();

      rafRef.current = requestAnimationFrame(tick);
    };

    // Resize handler
    const onResize = () => {
      setSize();
      setLines();
    };

    // Initialize
    setSize();
    setLines();

    // Bind events
    window.addEventListener('resize', onResize);
    window.addEventListener('mousemove', onMouseMove);
    containerRef.current.addEventListener('touchmove', onTouchMove, { passive: false });

    // Start animation
    rafRef.current = requestAnimationFrame(tick);

    return () => {
      if (rafRef.current) cancelAnimationFrame(rafRef.current);
      window.removeEventListener('resize', onResize);
      window.removeEventListener('mousemove', onMouseMove);
      if (containerRef.current) {
        containerRef.current.removeEventListener('touchmove', onTouchMove);
      }
    };
  }, [strokeColor]);

  return (
    <div
      ref={containerRef}
      className={`waves-background ${className}`}
      style={{
        backgroundColor,
        position: 'fixed',
        top: 0,
        left: 0,
        width: '100%',
        height: '100%',
        overflow: 'hidden',
        zIndex: -1,
        pointerEvents: 'none',
      }}
    >
      <svg
        ref={svgRef}
        style={{ display: 'block', width: '100%', height: '100%' }}
        xmlns="http://www.w3.org/2000/svg"
      />
    </div>
  );
}

// Export to window
window.WavesBackground = WavesBackground;
