import React, { useEffect, useRef, useState } from 'react';

interface WaveConfig {
  color?: string;
  amplitude?: number;
  frequency?: number;
  phaseOffset?: number;
  strokeWidth?: number;
}

interface WaveformLoaderProps {
  className?: string;
  height?: number;
  speed?: number; // radians per second
  waves?: WaveConfig[];
}

const DEFAULT_WAVES: WaveConfig[] = [
  {
    color: '#FFFFFF',
    amplitude: 18,
    frequency: 1.5,
    phaseOffset: 0,
    strokeWidth: 1,
  },
  {
    color: '#FFFFFF',
    amplitude: 12,
    frequency: 1.2,
    phaseOffset: Math.PI / 2,
    strokeWidth: 1,
  },
  {
    color: '#FFFFFF',
    amplitude: 8,
    frequency: 2,
    phaseOffset: Math.PI,
    strokeWidth: 1,
  },
];

const WaveformLoader: React.FC<WaveformLoaderProps> = ({
  className = '',
  height = 60,
  speed = 2,
  waves = DEFAULT_WAVES,
}) => {
  const [phase, setPhase] = useState(0);
  const [containerWidth, setContainerWidth] = useState(0);
  const containerRef = useRef<HTMLDivElement | null>(null);
  const requestRef = useRef<number | null>(null);
  const lastTimeRef = useRef<number | null>(null);

  // Animation loop
  useEffect(() => {
    const animate = (time: number) => {
      if (lastTimeRef.current !== null) {
        const delta = (time - lastTimeRef.current) / 1000;
        setPhase((prev) => prev + speed * delta);
      }
      lastTimeRef.current = time;
      requestRef.current = requestAnimationFrame(animate);
    };
    requestRef.current = requestAnimationFrame(animate);
    return () => {
      if (requestRef.current) cancelAnimationFrame(requestRef.current);
    };
  }, [speed]);

  // Responsive width
  useEffect(() => {
    const updateWidth = () => {
      if (containerRef.current) {
        setContainerWidth(containerRef.current.offsetWidth);
      }
    };
    updateWidth();
    window.addEventListener('resize', updateWidth);
    return () => {
      window.removeEventListener('resize', updateWidth);
    };
  }, []);

  // Generate the sine wave path
  const getPath = (
    amplitude: number,
    frequency: number,
    phaseOffset: number
  ) => {
    const width = containerWidth || 300;
    const points = 120;
    const path: string[] = [];
    for (let i = 0; i <= points; i++) {
      const x = (i / points) * width;
      const y =
        height / 2 +
        Math.sin(2 * Math.PI * frequency * (i / points) + phase + phaseOffset) *
          amplitude;
      path.push(i === 0 ? `M ${x},${y}` : `L ${x},${y}`);
    }
    return path.join(' ');
  };

  return (
    <div ref={containerRef} className={className} style={{ width: '100%' }}>
      <svg
        width='100%'
        height={height}
        viewBox={`0 0 ${containerWidth || 300} ${height}`}
        style={{ display: 'block' }}
        preserveAspectRatio='none'
      >
        {waves.map((wave, idx) => (
          <path
            key={idx}
            d={getPath(
              wave.amplitude ?? 18,
              wave.frequency ?? 1.5,
              wave.phaseOffset ?? 0
            )}
            stroke={wave.color ?? '#222'}
            strokeWidth={wave.strokeWidth ?? 1}
            fill='none'
            strokeLinecap='round'
          />
        ))}
      </svg>
    </div>
  );
};

export default WaveformLoader;
