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

/**
 * WaveformVisualizerProps - Propriétés du composant WaveformVisualizer
 *
 * @interface WaveformVisualizerProps
 */
interface WaveformVisualizerProps {
  /**
   * URL de l'audio source (optionnel, pour générer la waveform)
   */
  audioUrl?: string;

  /**
   * Données de waveform pré-calculées (valeurs entre 0.0 et 1.0)
   * Si non fourni, génère des données mock
   */
  waveformData?: number[];

  /**
   * Progression de la lecture (0 à 100)
   */
  progress: number;

  /**
   * Fonction appelée lors du clic sur la waveform pour naviguer
   *
   * @param {number} percentage - Pourcentage cliqué (0 à 100)
   */
  onSeek: (percentage: number) => void;

  /**
   * Hauteur de la waveform en pixels
   *
   * @default 64
   */
  height?: number;

  /**
   * Couleur des barres non jouées
   *
   * @default '#374054' (sumi-bg-hover)
   */
  color?: string;

  /**
   * Couleur des barres jouées
   *
   * @default '#00FFF7' (sumi-accent)
   */
  playedColor?: string;
}

/**
 * WaveformVisualizer - Composant de visualisation de waveform audio
 *
 * Composant pour afficher une waveform audio interactive avec :
 * - Visualisation des données audio
 * - Indicateur de progression
 * - Navigation par clic
 * - Support pour données pré-calculées ou génération automatique
 *
 * @example
 * ```tsx
 * // Waveform avec données pré-calculées
 * <WaveformVisualizer
 *   waveformData={waveformData}
 *   progress={currentProgress}
 *   onSeek={(percentage) => seekTo(percentage)}
 * />
 * ```
 *
 * @example
 * ```tsx
 * // Waveform avec génération automatique
 * <WaveformVisualizer
 *   audioUrl="/audio.mp3"
 *   progress={50}
 *   onSeek={handleSeek}
 *   height={80}
 * />
 * ```
 *
 * @component
 * @param {WaveformVisualizerProps} props - Propriétés du composant
 * @returns {JSX.Element} Canvas avec waveform interactive
 */

export const WaveformVisualizer: React.FC<WaveformVisualizerProps> = ({
  waveformData,
  progress,
  onSeek,
  height = 64,
  color = 'var(--sumi-bg-hover)',
  playedColor = 'var(--sumi-viz-indigo)',
}) => {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const [data, setData] = useState<number[]>([]);

  // Initialize or generate mock data if none provided
  useEffect(() => {
    if (waveformData && waveformData.length > 0) {
      setData(waveformData);
    } else {
      // Generate mock waveform
      const mockData = Array.from(
        { length: 100 },
        () => Math.random() * 0.8 + 0.2,
      );
      setData(mockData);
    }
  }, [waveformData]);

  // Draw loop
  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;

    const ctx = canvas.getContext('2d');
    if (!ctx) return;

    const dpr = window.devicePixelRatio || 1;
    const width = canvas.offsetWidth;
    const drawHeight = height;

    canvas.width = width * dpr;
    canvas.height = drawHeight * dpr;
    ctx.scale(dpr, dpr);

    ctx.clearRect(0, 0, width, drawHeight);

    const barWidth = width / data.length;
    const gap = 1;
    const effectiveBarWidth = Math.max(1, barWidth - gap);

    // Resolve CSS vars to hex values (canvas can't resolve var() directly)
    const styles = getComputedStyle(canvas);
    const resolve = (c: string) =>
      c.startsWith('var(')
        ? styles.getPropertyValue(c.slice(4, -1).trim()).trim() || c
        : c;
    const resolvedColor = resolve(color);
    const resolvedPlayed = resolve(playedColor);

    data.forEach((val, i) => {
      const x = i * barWidth;
      const barHeight = val * drawHeight;
      const y = (drawHeight - barHeight) / 2;

      // Determine color based on progress
      const isPlayed = (i / data.length) * 100 <= progress;
      ctx.fillStyle = isPlayed ? resolvedPlayed : resolvedColor;

      // Draw rounded rect equivalent
      ctx.fillRect(x, y, effectiveBarWidth, barHeight);
    });
  }, [data, progress, height, color, playedColor]);

  const handleClick = (e: React.MouseEvent<HTMLCanvasElement>) => {
    const rect = e.currentTarget.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const percentage = (x / rect.width) * 100;
    onSeek(Math.min(100, Math.max(0, percentage)));
  };

  return (
    <canvas
      ref={canvasRef}
      style={{ width: '100%', height: `${height}px` }}
      onClick={handleClick}
      className="cursor-pointer hover:opacity-90 transition-opacity"
    />
  );
};
