import React, { useMemo, useCallback, useState, useRef } from 'react';
import { VirtualizedList } from '@/components/ui/virtualized-list';
import { OptimizedImage } from '@/components/ui/optimized-image';
import { usePerformanceOptimization } from '@/hooks/usePerformanceOptimization';
import { Track } from '@/types/api';
import { formatDuration, formatFileSize } from '@/utils/format';
import { formatDistanceToNow } from 'date-fns';
import { fr } from 'date-fns/locale';

interface VirtualizedTrackListProps {
  tracks: Track[];
  hasNextPage: boolean;
  isFetching: boolean;
  fetchNextPage: () => void;
  onTrackSelect?: (track: Track) => void;
  onTrackPlay?: (track: Track) => void;
  onTrackEdit?: (track: Track) => void;
  onTrackDelete?: (track: Track) => void;
  className?: string;
  searchQuery?: string;
  sortBy?: 'name' | 'artist' | 'duration' | 'created_at';
  sortOrder?: 'asc' | 'desc';
}

const TRACK_HEIGHT = 80; // Hauteur estimée d'une track
const CONTAINER_HEIGHT = 600; // Hauteur du conteneur de tracks

export function VirtualizedTrackList({
  tracks,
  hasNextPage,
  isFetching,
  fetchNextPage,
  onTrackSelect,
  onTrackPlay,
  onTrackEdit,
  onTrackDelete,
  className = '',
  searchQuery = '',
  sortBy = 'created_at',
  sortOrder = 'desc',
}: VirtualizedTrackListProps) {
  const [selectedTrackId, setSelectedTrackId] = useState<string | null>(null);
  const [hoveredTrackId, setHoveredTrackId] = useState<string | null>(null);
  const containerRef = useRef<HTMLDivElement>(null);

  // Filtrage et tri des tracks avec mémorisation
  const filteredAndSortedTracks = useMemo(() => {
    let filteredTracks = tracks;

    // Filtrage par recherche
    if (searchQuery) {
      const query = searchQuery.toLowerCase();
      filteredTracks = tracks.filter(track =>
        track.title.toLowerCase().includes(query) ||
        track.artist?.toLowerCase().includes(query) ||
        track.album?.toLowerCase().includes(query)
      );
    }

    // Tri
    filteredTracks.sort((a, b) => {
      let aValue: any, bValue: any;

      switch (sortBy) {
        case 'name':
          aValue = a.title.toLowerCase();
          bValue = b.title.toLowerCase();
          break;
        case 'artist':
          aValue = (a.artist || '').toLowerCase();
          bValue = (b.artist || '').toLowerCase();
          break;
        case 'duration':
          aValue = a.duration || 0;
          bValue = b.duration || 0;
          break;
        case 'created_at':
        default:
          aValue = new Date(a.created_at).getTime();
          bValue = new Date(b.created_at).getTime();
          break;
      }

      if (sortOrder === 'asc') {
        return aValue < bValue ? -1 : aValue > bValue ? 1 : 0;
      } else {
        return aValue > bValue ? -1 : aValue < bValue ? 1 : 0;
      }
    });

    return filteredTracks;
  }, [tracks, searchQuery, sortBy, sortOrder]);

  // Gestion des sélections avec performance
  const handleTrackSelect = useCallback((track: Track) => {
    setSelectedTrackId(track.id);
    onTrackSelect?.(track);
  }, [onTrackSelect]);

  const handleTrackPlay = useCallback((track: Track, event: React.MouseEvent) => {
    event.stopPropagation();
    onTrackPlay?.(track);
  }, [onTrackPlay]);

  const handleTrackEdit = useCallback((track: Track, event: React.MouseEvent) => {
    event.stopPropagation();
    onTrackEdit?.(track);
  }, [onTrackEdit]);

  const handleTrackDelete = useCallback((track: Track, event: React.MouseEvent) => {
    event.stopPropagation();
    onTrackDelete?.(track);
  }, [onTrackDelete]);

  // Rendu d'une track individuelle avec mémorisation
  const renderTrack = useCallback((track: Track, index: number) => {
    const isSelected = selectedTrackId === track.id;
    const isHovered = hoveredTrackId === track.id;

    return (
      <div
        key={track.id}
        className={`flex items-center space-x-4 p-4 border-b border-gray-200 hover:bg-gray-50 cursor-pointer transition-colors ${
          isSelected ? 'bg-blue-50 border-blue-200' : ''
        } ${isHovered ? 'shadow-sm' : ''}`}
        onClick={() => handleTrackSelect(track)}
        onMouseEnter={() => setHoveredTrackId(track.id)}
        onMouseLeave={() => setHoveredTrackId(null)}
        style={{ minHeight: TRACK_HEIGHT }}
      >
        {/* Image de la track */}
        <div className="flex-shrink-0 w-12 h-12">
          <OptimizedImage
            src={track.cover_url || '/images/default-track-cover.png'}
            alt={track.title}
            width={48}
            height={48}
            className="rounded-lg object-cover"
            priority={index < 10} // Priorité pour les 10 premières tracks
          />
        </div>

        {/* Informations de la track */}
        <div className="flex-1 min-w-0">
          <div className="flex items-center justify-between">
            <div className="flex-1 min-w-0">
              <h3 className="text-sm font-medium text-gray-900 truncate">
                {track.title}
              </h3>
              <p className="text-sm text-gray-500 truncate">
                {track.artist || 'Artiste inconnu'}
                {track.album && ` • ${track.album}`}
              </p>
            </div>

            {/* Actions de la track */}
            <div className="flex items-center space-x-2 ml-4">
              <button
                onClick={(e) => handleTrackPlay(track, e)}
                className="p-2 text-gray-400 hover:text-blue-500 transition-colors"
                title="Lire"
              >
                <svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
                  <path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8v4a1 1 0 001.555.832l3-2a1 1 0 000-1.664l-3-2z" clipRule="evenodd" />
                </svg>
              </button>

              <button
                onClick={(e) => handleTrackEdit(track, e)}
                className="p-2 text-gray-400 hover:text-green-500 transition-colors"
                title="Modifier"
              >
                <svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
                  <path d="M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z" />
                </svg>
              </button>

              <button
                onClick={(e) => handleTrackDelete(track, e)}
                className="p-2 text-gray-400 hover:text-red-500 transition-colors"
                title="Supprimer"
              >
                <svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
                  <path fillRule="evenodd" d="M9 2a1 1 0 000 2h2a1 1 0 100-2H9z" clipRule="evenodd" />
                  <path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clipRule="evenodd" />
                </svg>
              </button>
            </div>
          </div>

          {/* Métadonnées de la track */}
          <div className="mt-2 flex items-center space-x-4 text-xs text-gray-500">
            {track.duration && (
              <span>{formatDuration(track.duration)}</span>
            )}
            {track.file_size && (
              <span>{formatFileSize(track.file_size)}</span>
            )}
            <span>
              Ajouté {formatDistanceToNow(new Date(track.created_at), {
                addSuffix: true,
                locale: fr,
              })}
            </span>
            {track.genre && (
              <span className="px-2 py-1 bg-gray-100 rounded-full">
                {track.genre}
              </span>
            )}
          </div>

          {/* Barre de progression (si en cours de lecture) */}
          {track.is_playing && (
            <div className="mt-2 w-full bg-gray-200 rounded-full h-1">
              <div 
                className="bg-blue-500 h-1 rounded-full transition-all duration-300"
                style={{ width: `${track.progress || 0}%` }}
              />
            </div>
          )}
        </div>
      </div>
    );
  }, [
    selectedTrackId,
    hoveredTrackId,
    handleTrackSelect,
    handleTrackPlay,
    handleTrackEdit,
    handleTrackDelete,
  ]);

  // Gestion du scroll infini
  const handleItemsRendered = useCallback((startIndex: number, endIndex: number) => {
    // Charger plus de tracks si on approche de la fin
    if (endIndex >= filteredAndSortedTracks.length - 5 && hasNextPage && !isFetching) {
      fetchNextPage();
    }
  }, [filteredAndSortedTracks.length, hasNextPage, isFetching, fetchNextPage]);

  // Message vide
  if (filteredAndSortedTracks.length === 0 && !isFetching) {
    return (
      <div className={`flex items-center justify-center h-full ${className}`}>
        <div className="text-center">
          <div className="text-gray-400 text-6xl mb-4">🎵</div>
          <p className="text-gray-500">
            {searchQuery ? 'Aucune track trouvée' : 'Aucune track dans votre bibliothèque'}
          </p>
          <p className="text-sm text-gray-400 mt-2">
            {searchQuery ? 'Essayez avec d\'autres mots-clés' : 'Commencez par ajouter des tracks !'}
          </p>
        </div>
      </div>
    );
  }

  return (
    <div className={`relative ${className}`}>
      {/* Indicateur de chargement */}
      {isFetching && (
        <div className="absolute top-0 left-0 right-0 z-10 bg-white/80 backdrop-blur-sm">
          <div className="flex justify-center items-center py-4">
            <div className="animate-spin rounded-full h-6 w-6 border-b-2 border-blue-500"></div>
            <span className="ml-2 text-sm text-gray-500">Chargement des tracks...</span>
          </div>
        </div>
      )}

      {/* Liste virtualisée des tracks */}
      <VirtualizedList
        ref={containerRef}
        items={filteredAndSortedTracks}
        itemHeight={TRACK_HEIGHT}
        containerHeight={CONTAINER_HEIGHT}
        renderItem={renderTrack}
        onItemsRendered={handleItemsRendered}
        className="scroll-smooth"
        overscan={10}
      />

      {/* Statistiques de la liste */}
      <div className="mt-4 text-sm text-gray-500 text-center">
        {filteredAndSortedTracks.length} track{filteredAndSortedTracks.length > 1 ? 's' : ''}
        {searchQuery && ` trouvée${filteredAndSortedTracks.length > 1 ? 's' : ''}`}
      </div>
    </div>
  );
}

// Hook pour gérer l'état des tracks avec pagination
export function useTrackList(initialTracks: Track[] = []) {
  const [tracks, setTracks] = useState<Track[]>(initialTracks);
  const [hasNextPage, setHasNextPage] = useState(true);
  const [isFetching, setIsFetching] = useState(false);
  const [page, setPage] = useState(1);

  const fetchTracks = useCallback(async (pageNum: number = 1) => {
    if (isFetching) return;
    
    setIsFetching(true);
    try {
      const response = await fetch(`/api/library/tracks?page=${pageNum}&limit=50`);
      const data = await response.json();
      
      if (pageNum === 1) {
        setTracks(data.tracks || []);
      } else {
        setTracks(prev => [...prev, ...(data.tracks || [])]);
      }
      
      setHasNextPage(data.has_next_page || false);
      setPage(pageNum);
    } catch (error) {
      console.error('Erreur lors du chargement des tracks:', error);
    } finally {
      setIsFetching(false);
    }
  }, [isFetching]);

  const fetchNextPage = useCallback(() => {
    if (hasNextPage && !isFetching) {
      fetchTracks(page + 1);
    }
  }, [hasNextPage, isFetching, fetchTracks, page]);

  const addTrack = useCallback((track: Track) => {
    setTracks(prev => [track, ...prev]);
  }, []);

  const updateTrack = useCallback((trackId: string, updates: Partial<Track>) => {
    setTracks(prev => 
      prev.map(track => 
        track.id === trackId ? { ...track, ...updates } : track
      )
    );
  }, []);

  const deleteTrack = useCallback((trackId: string) => {
    setTracks(prev => prev.filter(track => track.id !== trackId));
  }, []);

  return {
    tracks,
    hasNextPage,
    isFetching,
    fetchNextPage,
    addTrack,
    updateTrack,
    deleteTrack,
  };
}
