/**
 * Composant AudioPlayer - Intégration complète
 * Assemble tous les composants du player pour une expérience complète
 */

import { useRef, useEffect, useState } from 'react';
import { usePlayer } from '../hooks/usePlayer';
import { useStreamSync } from '../hooks/useStreamSync';
import { usePlayerStore } from '../store/playerStore';
import { useKeyboardShortcuts } from '../hooks/useKeyboardShortcuts';
import { TrackInfo } from './TrackInfo';
import { PlayPauseButton } from './PlayPauseButton';
import { NextPreviousButtons } from './NextPreviousButtons';
import { ProgressBar } from './ProgressBar';
import { TimeDisplay } from './TimeDisplay';
import { VolumeControl } from './VolumeControl';
import { RepeatShuffleButtons } from './RepeatShuffleButtons';
import { QualitySelector } from './QualitySelector';
import { PlaybackSpeedControl } from './PlaybackSpeedControl';
import { PlayerError } from './PlayerError';
import { PlayerLoading } from './PlayerLoading';
import { cn } from '@/lib/utils';
import { Badge } from '@/components/ui/badge';
import { Wifi, WifiOff } from 'lucide-react';
import type { AudioQuality } from './QualitySelector';
import type { PlaybackSpeed } from './PlaybackSpeedControl';

export interface AudioPlayerProps {
  className?: string;
  autoPlay?: boolean;
  preload?: 'none' | 'metadata' | 'auto';
  showQualitySelector?: boolean;
  showSpeedControl?: boolean;
  compact?: boolean;
}

export function AudioPlayer({
  className,
  autoPlay = false,
  preload = 'metadata',
  showQualitySelector = true,
  showSpeedControl = true,
  compact = false,
}: AudioPlayerProps) {
  const audioRef = useRef<HTMLAudioElement>(null);
  const player = usePlayer(audioRef);
  const [error, setError] = useState<Error | null>(null);
  const [isLoading, setIsLoading] = useState(false);
  const [quality, setQuality] = useState<AudioQuality>('auto');
  const [playbackSpeed, setPlaybackSpeed] = useState<PlaybackSpeed>(1);
  const currentTrack = usePlayerStore((state) => state.currentTrack);

  // Intégration de la synchronisation (Session ID mocké pour l'instant ou via props)
  // Dans le futur, ça viendra du contexte de "Room" ou "Session"
  // On utilise l'ID de la track comme session ID temporaire pour le dev
  const sessionId = currentTrack?.id ? `session_${currentTrack.id}` : null;

  const { isSynced } = useStreamSync({
    sessionId,
    trackId: currentTrack?.id ?? null,
  });

  // Activer les raccourcis clavier
  useKeyboardShortcuts(player, {
    enabled: true,
    seekStep: 5,
    volumeStep: 5,
  });

  // Gérer le lifecycle de l'élément audio
  useEffect(() => {
    const audio = audioRef.current;
    if (!audio) return;

    // Configuration initiale
    audio.preload = preload;
    audio.autoplay = autoPlay;

    // Gérer les erreurs
    const handleError = () => {
      const error = new Error('Erreur de lecture audio');
      setError(error);
      setIsLoading(false);
    };

    // Gérer le chargement
    const handleLoadStart = () => {
      setIsLoading(true);
      setError(null);
    };

    const handleCanPlay = () => {
      setIsLoading(false);
      setError(null);
    };

    // Gérer la vitesse de lecture
    const updatePlaybackRate = () => {
      if (audio) {
        audio.playbackRate = playbackSpeed;
      }
    };

    audio.addEventListener('error', handleError);
    audio.addEventListener('loadstart', handleLoadStart);
    audio.addEventListener('canplay', handleCanPlay);
    updatePlaybackRate();

    return () => {
      audio.removeEventListener('error', handleError);
      audio.removeEventListener('loadstart', handleLoadStart);
      audio.removeEventListener('canplay', handleCanPlay);
    };
  }, [preload, autoPlay, playbackSpeed]);

  // Mettre à jour la vitesse de lecture quand elle change
  useEffect(() => {
    const audio = audioRef.current;
    if (audio) {
      audio.playbackRate = playbackSpeed;
    }
  }, [playbackSpeed]);

  const handlePlayPause = () => {
    if (player.isPlaying) {
      player.pause();
    } else {
      player.resume();
    }
  };

  const handleRetry = () => {
    setError(null);
    if (player.currentTrack) {
      player.play(player.currentTrack);
    }
  };

  const canGoNext =
    player.queue.length > 0 && player.currentIndex < player.queue.length - 1;
  const canGoPrevious = player.queue.length > 0 && player.currentIndex > 0;

  if (compact) {
    return (
      <div
        className={cn('flex items-center gap-4 p-4', className)}
        data-testid="audio-player"
      >
        <audio
          ref={audioRef}
          data-testid="audio-element"
          style={{ display: 'none' }}
          preload={preload}
          autoPlay={autoPlay}
        />

        {error && <PlayerError error={error} onRetry={handleRetry} />}

        {isLoading && <PlayerLoading isLoading={isLoading} size="sm" />}

        {player.currentTrack && !error && !isLoading && (
          <>
            <TrackInfo
              track={player.currentTrack}
              showCover={true}
              coverSize="sm"
              showMetadata={false}
            />
            <PlayPauseButton
              isPlaying={player.isPlaying}
              onClick={handlePlayPause}
              size="sm"
            />
            <NextPreviousButtons
              onNext={player.next}
              onPrevious={player.previous}
              canGoNext={canGoNext}
              canGoPrevious={canGoPrevious}
              size="sm"
            />
            <VolumeControl
              volume={player.volume}
              muted={player.muted}
              onVolumeChange={player.setVolume}
              onMuteToggle={player.toggleMute}
              showValue={false}
            />
          </>
        )}

        {!player.currentTrack && !error && (
          <div className="text-sm text-gray-500 dark:text-gray-400">
            Aucune piste sélectionnée
          </div>
        )}
      </div>
    );
  }

  return (
    <div
      className={cn(
        'bg-white dark:bg-gray-900 rounded-lg shadow-lg p-6',
        className,
      )}
      data-testid="audio-player"
    >
      {/* Élément audio HTML - invisible mais nécessaire pour la lecture */}
      <audio
        ref={audioRef}
        data-testid="audio-element"
        style={{ display: 'none' }}
        preload={preload}
        autoPlay={autoPlay}
      />

      {/* Gestion des erreurs */}
      {error && (
        <div className="mb-4">
          <PlayerError error={error} onRetry={handleRetry} />
        </div>
      )}

      {/* État de chargement */}
      {isLoading && (
        <div className="mb-4">
          <PlayerLoading
            isLoading={isLoading}
            message="Chargement de la piste..."
          />
        </div>
      )}

      {/* Contenu principal */}
      {player.currentTrack && !error && !isLoading && (
        <div className="space-y-6">
          {/* Informations de la piste */}
          <div>
            <TrackInfo
              track={player.currentTrack}
              showCover={true}
              coverSize="lg"
              showMetadata={true}
            />
          </div>

          {/* Barre de progression */}
          <div className="space-y-2">
            <ProgressBar
              currentTime={player.currentTime}
              duration={player.duration}
              onSeek={player.seek}
              showTooltip={true}
            />
            <div className="flex items-center justify-between">
              <TimeDisplay
                currentTime={player.currentTime}
                duration={player.duration}
              />
            </div>
          </div>

          {/* Contrôles principaux */}
          <div className="flex items-center justify-center gap-4">
            <RepeatShuffleButtons
              repeat={player.repeat}
              shuffle={player.shuffle}
              onRepeatChange={player.setRepeat}
              onShuffleToggle={player.toggleShuffle}
              size="md"
            />

            <NextPreviousButtons
              onNext={player.next}
              onPrevious={player.previous}
              canGoNext={canGoNext}
              canGoPrevious={canGoPrevious}
              size="md"
            />

            <PlayPauseButton
              isPlaying={player.isPlaying}
              onClick={handlePlayPause}
              size="lg"
              variant="default"
            />

            <NextPreviousButtons
              onNext={player.next}
              onPrevious={player.previous}
              canGoNext={canGoNext}
              canGoPrevious={canGoPrevious}
              size="md"
            />

            <VolumeControl
              volume={player.volume}
              muted={player.muted}
              onVolumeChange={player.setVolume}
              onMuteToggle={player.toggleMute}
              showValue={true}
              showSlider={true}
            />
          </div>

          {/* Contrôles avancés */}
          {(showQualitySelector || showSpeedControl) && (
            <div className="flex items-center justify-between gap-4 pt-4 border-t border-gray-200 dark:border-gray-700">
              {/* Sync Status Indicator */}
              <div className="flex items-center gap-2">
                <Badge
                  variant={isSynced ? 'success' : 'default'}
                  className={cn('gap-1', !isSynced && 'text-gray-500')}
                >
                  {isSynced ? (
                    <Wifi className="h-3 w-3" />
                  ) : (
                    <WifiOff className="h-3 w-3" />
                  )}
                  <span className="text-xs">{isSynced ? 'Sync' : 'Local'}</span>
                </Badge>
                {sessionId && !isSynced && (
                  <span className="text-xs text-muted-foreground hidden lg:inline">
                    Connecting to session...
                  </span>
                )}
              </div>

              <div className="flex items-center gap-4">
                {showSpeedControl && (
                  <div className="flex items-center gap-2">
                    <span className="text-sm text-gray-600 dark:text-gray-400">
                      Vitesse:
                    </span>
                    <PlaybackSpeedControl
                      currentSpeed={playbackSpeed}
                      onSpeedChange={setPlaybackSpeed}
                    />
                  </div>
                )}

                {showQualitySelector && (
                  <div className="flex items-center gap-2">
                    <span className="text-sm text-gray-600 dark:text-gray-400">
                      Qualité:
                    </span>
                    <QualitySelector
                      currentQuality={quality}
                      onQualityChange={setQuality}
                    />
                  </div>
                )}
              </div>
            </div>
          )}
        </div>
      )}

      {/* État vide */}
      {!player.currentTrack && !error && !isLoading && (
        <div className="text-center py-12">
          <div className="text-gray-500 dark:text-gray-400 mb-2">
            Aucune piste sélectionnée
          </div>
          <div className="text-sm text-gray-400 dark:text-gray-500">
            Sélectionnez une piste pour commencer la lecture
          </div>
        </div>
      )}
    </div>
  );
}

export default AudioPlayer;
