import { useState, useEffect, useRef } from 'react';
import { useDebounce } from '@/hooks/useDebounce';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import {
  usePlaylists,
  useAddTrackToPlaylist,
} from '@/features/playlists/hooks/usePlaylist';
import {
  tracksApi,
  type GetTracksParams,
} from '@/services/api/tracks';
import type { Track } from '@/features/tracks/types/track';
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import { VirtualizedList, useInfiniteScroll } from '@/components/ui/virtualized-list';
import {
  Upload,
  Search,
  Music,
  MoreVertical,
  Play,
  Plus,
  Filter,
  ArrowUpDown,
  Trash2,
  CheckSquare,
  X,
  Grid3x3,
  List,
  Heart,
  Clock,
} from 'lucide-react';
import { Input } from '@/components/ui/input';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
  DropdownMenuSub,
  DropdownMenuSubTrigger,
  DropdownMenuSubContent,
  DropdownMenuPortal,
  DropdownMenuLabel,
} from '@/components/ui/dropdown-menu';
import { Select } from '@/components/ui/select';
import { UploadModal } from '@/features/upload/components/UploadModal';
import { useToast } from '@/hooks/useToast';
import { Checkbox } from '@/components/ui/checkbox';
import { ErrorDisplay } from '@/components/ui/ErrorDisplay';
import { Pagination } from '@/components/navigation/Pagination';
import { ConfirmationDialog } from '@/components/ui/confirmation-dialog';
import { LoadingState } from '@/components/ui/LoadingState';
import { logger } from '@/utils/logger';
import { parseApiError } from '@/utils/apiErrorHandler';
import { cn } from '@/lib/utils';

type SortField = 'created_at' | 'title' | 'popularity';
type SortOrder = 'asc' | 'desc';
type ViewMode = 'grid' | 'list';

/**
 * Library Page Premium - Version MVP avec UI moderne et professionnelle
 * Grille de tracks avec design premium
 */
export default function LibraryPagePremium() {
  const queryClient = useQueryClient();
  const toast = useToast();
  const [limit] = useState(50);
  const [isUploadModalOpen, setIsUploadModalOpen] = useState(false);
  const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
  const [viewMode, setViewMode] = useState<ViewMode>('grid');

  const [searchTerm, setSearchTerm] = useState('');
  // Action 2.4.1.2: Debounce search term to reduce API calls
  const debouncedSearchTerm = useDebounce(searchTerm, 300);
  const [genreFilter, setGenreFilter] = useState<string>('');
  const [formatFilter, setFormatFilter] = useState<string>('');
  const [sortBy, setSortBy] = useState<SortField>('created_at');
  const [sortOrder, setSortOrder] = useState<SortOrder>('desc');

  const [selectedTracks, setSelectedTracks] = useState<Set<string>>(new Set());
  const [isBulkMode, setIsBulkMode] = useState(false);
  const [mutationError, setMutationError] = useState<Error | null>(null);
  const [retryCount, setRetryCount] = useState(0);
  const lastMutationRef = useRef<(() => Promise<void>) | null>(null);

  const queryParams: GetTracksParams = {
    limit,
    sortBy,
    sortOrder,
  };

  if (genreFilter) {
    queryParams.genre = genreFilter;
  }
  if (formatFilter) {
    queryParams.format = formatFilter;
  }
  // Use debounced search term for API calls
  if (debouncedSearchTerm.trim()) {
    queryParams.search = debouncedSearchTerm.trim();
  }

  const {
    data: tracksInfiniteData,
    isLoading: isTracksLoading,
    isError: isTracksError,
    error: tracksError,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
  } = useInfiniteQuery({
    queryKey: ['tracks', 'library', queryParams, debouncedSearchTerm],
    queryFn: ({ pageParam = 1 }) =>
      tracksApi.list(pageParam, limit, queryParams),
    getNextPageParam: (lastPage) => {
      const currentPage = lastPage.pagination?.page || 1;
      const totalPages = lastPage.pagination?.total_pages || 1;
      return currentPage < totalPages ? currentPage + 1 : undefined;
    },
    initialPageParam: 1,
  });

  const { data: playlistsData } = usePlaylists();
  const addTrackToPlaylistMutation = useAddTrackToPlaylist();

  // Action 2.2.1.1: Remove client-side filtering - backend handles all filters
  // Backend returns filtered results, no need for client-side filtering
  const filteredTracks: Track[] = tracksData?.tracks || [];

  // Action 2.4.1.4: Use debounced search term for page reset to fix race condition
  // Reset infinite query when search term changes (handled by query key)

  const genres = Array.from(
    new Set(
      filteredTracks.map((t) => t.genre).filter((g): g is string => !!g) || [],
    ),
  ).sort();
  const formats = Array.from(
    new Set(
      filteredTracks.map((t) => t.format).filter((f): f is string => !!f) || [],
    ),
  ).sort();

  const handleAddToPlaylist = async (playlistId: string, trackId: string) => {
    // Action 3.4.1.3: Store mutation for retry
    const performMutation = async () => {
      await addTrackToPlaylistMutation.mutateAsync({ playlistId, trackId });
      toast.success('Piste ajoutée à la playlist');
      setMutationError(null);
      setRetryCount(0);
      lastMutationRef.current = null;
    };

    lastMutationRef.current = performMutation;
    setMutationError(null);

    try {
      await performMutation();
    } catch (error) {
      logger.error('Failed to add track to playlist:', { error });
      const apiError = parseApiError(error);
      setMutationError(
        new Error(
          apiError.message || "Impossible d'ajouter la piste à la playlist",
        ),
      );
    }
  };

  const handleOpenUpload = () => {
    setIsUploadModalOpen(true);
  };

  const handleCloseUpload = () => {
    setIsUploadModalOpen(false);
    queryClient.invalidateQueries({ queryKey: ['tracks'] });
  };

  const toggleTrackSelection = (trackId: string) => {
    setSelectedTracks((prev) => {
      const next = new Set(prev);
      if (next.has(trackId)) {
        next.delete(trackId);
      } else {
        next.add(trackId);
      }
      return next;
    });
  };

  const toggleSelectAll = () => {
    if (selectedTracks.size === filteredTracks.length) {
      setSelectedTracks(new Set());
    } else {
      setSelectedTracks(new Set(filteredTracks.map((t) => t.id)));
    }
  };

  const handleBulkDelete = async () => {
    if (selectedTracks.size === 0) return;
    setShowDeleteConfirm(true);
  };

  const confirmBulkDelete = async () => {
    if (selectedTracks.size === 0) return;

    // Action 3.4.1.3: Store mutation for retry
    const trackIds = Array.from(selectedTracks);
    const performMutation = async () => {
      await tracksApi.batchDelete(trackIds);
      toast.success(`${trackIds.length} piste(s) supprimée(s)`);
      setSelectedTracks(new Set());
      setIsBulkMode(false);
      setShowDeleteConfirm(false);
      queryClient.invalidateQueries({ queryKey: ['tracks', 'library'] });
      setMutationError(null);
      setRetryCount(0);
      lastMutationRef.current = null;
    };

    lastMutationRef.current = performMutation;
    setMutationError(null);

    try {
      await performMutation();
    } catch (error) {
      logger.error('Failed to bulk delete tracks:', { error });
      const apiError = parseApiError(error);
      setMutationError(
        new Error(apiError.message || 'Impossible de supprimer les pistes'),
      );
      setShowDeleteConfirm(false);
    }
  };

  const handleBulkUpdate = async (updates: { is_public?: boolean }) => {
    if (selectedTracks.size === 0) return;

    // Action 3.4.1.3: Store mutation for retry
    const trackIds = Array.from(selectedTracks);
    const performMutation = async () => {
      await tracksApi.batchUpdate(trackIds, updates);
      toast.success(`${trackIds.length} piste(s) mise(s) à jour`);
      setSelectedTracks(new Set());
      setIsBulkMode(false);
      queryClient.invalidateQueries({ queryKey: ['tracks', 'library'] });
      setMutationError(null);
      setRetryCount(0);
      lastMutationRef.current = null;
    };

    lastMutationRef.current = performMutation;
    setMutationError(null);

    try {
      await performMutation();
    } catch (error: unknown) {
      const apiError = parseApiError(error);
      logger.error('Erreur lors de la mise à jour des pistes:', {
        error: apiError.message,
      });
      setMutationError(new Error(apiError.message));
    }
  };

  // Action 3.4.1.3: Retry handler for failed mutations
  const handleRetry = async () => {
    if (!lastMutationRef.current || retryCount >= 3) return;

    setRetryCount((prev) => prev + 1);
    try {
      await lastMutationRef.current();
    } catch (error) {
      // Error will be handled by the mutation function
    }
  };

  const handleSort = (field: SortField) => {
    if (sortBy === field) {
      setSortOrder(sortOrder === 'asc' ? 'desc' : 'asc');
    } else {
      setSortBy(field);
      setSortOrder('desc');
    }
  };

  const formatDuration = (seconds: number) => {
    const mins = Math.floor(seconds / 60);
    const secs = seconds % 60;
    return `${mins}:${secs.toString().padStart(2, '0')}`;
  };

  return (
    <div className="space-y-6 animate-fade-in">
      {mutationError && (
        <ErrorDisplay
          error={mutationError}
          variant="banner"
          severity="error"
          onRetry={retryCount < 3 ? handleRetry : undefined}
          onDismiss={() => {
            setMutationError(null);
            setRetryCount(0);
            lastMutationRef.current = null;
          }}
        />
      )}
      {/* Header */}
      <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
        <div>
          <h1 className="text-3xl font-bold text-white tracking-tight">
            Bibliothèque
          </h1>
          <p className="text-kodo-secondary text-sm mt-1">
            Gérez et organisez vos fichiers audio
          </p>
        </div>
        <div className="flex items-center gap-2">
          {isBulkMode && selectedTracks.size > 0 && (
            <>
              <Button
                variant="destructive"
                onClick={handleBulkDelete}
                size="sm"
              >
                <Trash2 className="mr-2 h-4 w-4" />
                Supprimer ({selectedTracks.size})
              </Button>
              <Button
                variant="outline"
                onClick={() => handleBulkUpdate({ is_public: true })}
                size="sm"
              >
                Public ({selectedTracks.size})
              </Button>
              <Button
                variant="outline"
                onClick={() => handleBulkUpdate({ is_public: false })}
                size="sm"
              >
                Privé ({selectedTracks.size})
              </Button>
            </>
          )}
          <Button
            variant={isBulkMode ? 'default' : 'outline'}
            onClick={() => {
              setIsBulkMode(!isBulkMode);
              setSelectedTracks(new Set());
            }}
            size="sm"
          >
            {isBulkMode ? (
              <>
                <X className="mr-2 h-4 w-4" />
                Annuler
              </>
            ) : (
              <>
                <CheckSquare className="mr-2 h-4 w-4" />
                Sélection
              </>
            )}
          </Button>
          <div className="flex items-center border border-white/10 rounded-lg overflow-hidden">
            <button
              onClick={() => setViewMode('grid')}
              className={cn(
                'p-2 transition-colors',
                viewMode === 'grid'
                  ? 'bg-kodo-cyan/20 text-kodo-cyan'
                  : 'text-kodo-secondary hover:text-white',
              )}
            >
              <Grid3x3 className="w-4 h-4" />
            </button>
            <button
              onClick={() => setViewMode('list')}
              className={cn(
                'p-2 transition-colors border-l border-white/10',
                viewMode === 'list'
                  ? 'bg-kodo-cyan/20 text-kodo-cyan'
                  : 'text-kodo-secondary hover:text-white',
              )}
            >
              <List className="w-4 h-4" />
            </button>
          </div>
          <Button onClick={handleOpenUpload} size="sm">
            <Upload className="mr-2 h-4 w-4" />
            Upload
          </Button>
        </div>
      </div>

      {/* Filters */}
      <Card>
        <CardContent className="p-4 space-y-4">
          <div className="relative">
            <Search className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-kodo-secondary" />
            <Input
              placeholder="Rechercher dans la bibliothèque..."
              value={searchTerm}
              onChange={(e) => setSearchTerm(e.target.value)}
              className="pl-10"
            />
          </div>
          <div className="flex flex-wrap items-center gap-4">
            <div className="flex items-center gap-2">
              <Filter className="h-4 w-4 text-kodo-secondary" />
              <Select
                options={[
                  { value: '', label: 'Tous les genres' },
                  ...genres.map((genre) => ({ value: genre, label: genre })),
                ]}
                value={genreFilter}
                onChange={(value) =>
                  setGenreFilter(Array.isArray(value) ? value[0] : value)
                }
                placeholder="Tous les genres"
                className="w-[180px]"
              />
            </div>
            <Select
              options={[
                { value: '', label: 'Tous les formats' },
                ...formats.map((format) => ({ value: format, label: format })),
              ]}
              value={formatFilter}
              onChange={(value) =>
                setFormatFilter(Array.isArray(value) ? value[0] : value)
              }
              placeholder="Tous les formats"
              className="w-[180px]"
            />
            <div className="flex items-center gap-2 ml-auto">
              <span className="text-sm text-kodo-secondary">Trier par:</span>
              <DropdownMenu>
                <DropdownMenuTrigger asChild>
                  <Button variant="outline" size="sm">
                    <ArrowUpDown className="mr-2 h-4 w-4" />
                    {sortBy === 'created_at'
                      ? 'Date'
                      : sortBy === 'title'
                        ? 'Titre'
                        : 'Popularité'}
                    {sortOrder === 'asc' ? ' ↑' : ' ↓'}
                  </Button>
                </DropdownMenuTrigger>
                <DropdownMenuContent>
                  <DropdownMenuLabel>Trier par</DropdownMenuLabel>
                  <DropdownMenuItem onClick={() => handleSort('created_at')}>
                    Date{' '}
                    {sortBy === 'created_at' &&
                      (sortOrder === 'asc' ? '↑' : '↓')}
                  </DropdownMenuItem>
                  <DropdownMenuItem onClick={() => handleSort('title')}>
                    Titre{' '}
                    {sortBy === 'title' && (sortOrder === 'asc' ? '↑' : '↓')}
                  </DropdownMenuItem>
                  <DropdownMenuItem onClick={() => handleSort('popularity')}>
                    Popularité{' '}
                    {sortBy === 'popularity' &&
                      (sortOrder === 'asc' ? '↑' : '↓')}
                  </DropdownMenuItem>
                </DropdownMenuContent>
              </DropdownMenu>
            </div>
          </div>
        </CardContent>
      </Card>

      {/* Tracks Display */}
      {isTracksLoading ? (
        <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
          {Array(8)
            .fill(0)
            .map((_, i) => (
              <Card key={i} className="animate-pulse">
                <CardContent className="p-6">
                  <div className="aspect-square bg-white/5 rounded-xl mb-4" />
                  <div className="h-4 bg-white/5 rounded mb-2" />
                  <div className="h-3 bg-white/5 rounded w-2/3" />
                </CardContent>
              </Card>
            ))}
        </div>
      ) : isTracksError ? (
        <ErrorDisplay
          error={
            tracksError ||
            new Error('Une erreur est survenue lors du chargement des pistes')
          }
          variant="card"
          severity="error"
          context={{
            action: 'fetching tracks',
            resource: 'tracks',
          }}
          onRetry={() => {
            queryClient.invalidateQueries({ queryKey: ['tracks', 'library'] });
          }}
        />
      ) : viewMode === 'grid' ? (
        <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
          {filteredTracks.map((track) => (
            <Card
              key={track.id}
              className={cn(
                'group cursor-pointer hover:border-kodo-cyan/30 transition-all duration-300 overflow-hidden',
                selectedTracks.has(track.id) &&
                  'border-kodo-cyan ring-2 ring-kodo-cyan/20',
              )}
              onClick={() => isBulkMode && toggleTrackSelection(track.id)}
            >
              <CardContent className="p-0">
                <div className="relative aspect-square bg-gradient-to-br from-kodo-ink to-kodo-graphite overflow-hidden">
                  {isBulkMode && (
                    <div className="absolute top-2 left-2 z-10">
                      <Checkbox
                        checked={selectedTracks.has(track.id)}
                        onCheckedChange={() => toggleTrackSelection(track.id)}
                        onClick={(e) => e.stopPropagation()}
                      />
                    </div>
                  )}
                  <div className="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity bg-black/40">
                    <Button
                      size="icon"
                      variant="premium"
                      className="rounded-full w-14 h-14 shadow-glow-cyan"
                      onClick={(e) => {
                        e.stopPropagation();
                        // TODO: Play track
                      }}
                    >
                      <Play className="w-6 h-6 ml-1" fill="currentColor" />
                    </Button>
                  </div>
                  <div className="absolute bottom-2 right-2 bg-black/60 backdrop-blur-sm px-2 py-1 rounded text-xs text-white font-mono">
                    {formatDuration(track.duration)}
                  </div>
                </div>
                <div className="p-4">
                  <h3 className="font-semibold text-white mb-1 line-clamp-1 group-hover:text-kodo-cyan transition-colors">
                    {track.title}
                  </h3>
                  <p className="text-sm text-kodo-secondary mb-2 line-clamp-1">
                    {track.artist || 'Artiste inconnu'}
                  </p>
                  <div className="flex items-center justify-between text-xs text-kodo-secondary">
                    <span className="flex items-center gap-1">
                      <Clock className="w-3 h-3" />
                      {new Date(track.created_at).toLocaleDateString('fr-FR')}
                    </span>
                    {track.genre && (
                      <span className="px-2 py-0.5 bg-kodo-cyan/10 text-kodo-cyan rounded-full">
                        {track.genre}
                      </span>
                    )}
                  </div>
                </div>
              </CardContent>
            </Card>
          ))}
          {filteredTracks.length === 0 && (
            <div className="col-span-full">
              <Card>
                <CardContent className="p-12 text-center">
                  <Music className="w-16 h-16 text-kodo-secondary mx-auto mb-4" />
                  <p className="text-lg font-semibold text-white mb-2">
                    Aucun titre trouvé
                  </p>
                  <p className="text-kodo-secondary mb-4">
                    {searchTerm
                      ? "Essayez avec d'autres termes de recherche"
                      : 'Commencez par uploader votre premier track'}
                  </p>
                  {!searchTerm && (
                    <Button onClick={handleOpenUpload}>
                      <Upload className="mr-2 h-4 w-4" />
                      Upload Track
                    </Button>
                  )}
                </CardContent>
              </Card>
            </div>
          )}
        </div>
      ) : (
        <Card>
          <CardContent className="p-0">
            {filteredTracks.length === 0 ? (
              <div className="p-12 text-center">
                <Music className="w-16 h-16 text-kodo-secondary mx-auto mb-4" />
                <p className="text-lg font-semibold text-white mb-2">
                  Aucun titre trouvé
                </p>
                <p className="text-kodo-secondary mb-4">
                  {searchTerm
                    ? "Essayez avec d'autres termes de recherche"
                    : 'Commencez par uploader votre premier track'}
                </p>
                {!searchTerm && (
                  <Button onClick={handleOpenUpload}>
                    <Upload className="mr-2 h-4 w-4" />
                    Upload Track
                  </Button>
                )}
              </div>
            ) : (
              <VirtualizedList
                items={filteredTracks}
                itemHeight={88}
                containerHeight={600}
                className="divide-y divide-white/5"
                onItemsRendered={handleItemsRendered}
                renderItem={(track: Track, index: number) => (
                  <div
                    key={track.id}
                    className={cn(
                      'flex items-center gap-4 p-4 hover:bg-white/5 transition-colors cursor-pointer group',
                      selectedTracks.has(track.id) && 'bg-kodo-cyan/10',
                    )}
                    onClick={() => isBulkMode && toggleTrackSelection(track.id)}
                  >
                    {isBulkMode && (
                      <Checkbox
                        checked={selectedTracks.has(track.id)}
                        onCheckedChange={() => toggleTrackSelection(track.id)}
                        onClick={(e) => e.stopPropagation()}
                      />
                    )}
                    <div className="w-12 h-12 rounded-lg bg-gradient-to-br from-kodo-ink to-kodo-graphite flex items-center justify-center text-kodo-secondary font-mono text-xs">
                      {index + 1}
                    </div>
                    <div className="flex-1 min-w-0">
                      <h3 className="font-semibold text-white group-hover:text-kodo-cyan transition-colors truncate">
                        {track.title}
                      </h3>
                      <p className="text-sm text-kodo-secondary truncate">
                        {track.artist || 'Artiste inconnu'}
                      </p>
                    </div>
                    <div className="hidden md:flex items-center gap-4 text-sm text-kodo-secondary">
                      {track.genre && (
                        <span className="px-2 py-1 bg-kodo-cyan/10 text-kodo-cyan rounded">
                          {track.genre}
                        </span>
                      )}
                      <span className="flex items-center gap-1">
                        <Clock className="w-4 h-4" />
                        {formatDuration(track.duration)}
                      </span>
                    </div>
                    <DropdownMenu>
                      <DropdownMenuTrigger
                        asChild
                        onClick={(e) => e.stopPropagation()}
                      >
                        <Button variant="ghost" size="icon" className="h-8 w-8">
                          <MoreVertical className="h-4 w-4" />
                        </Button>
                      </DropdownMenuTrigger>
                      <DropdownMenuContent align="end">
                        <DropdownMenuSub>
                          <DropdownMenuSubTrigger>
                            <Plus className="mr-2 h-4 w-4" />
                            Ajouter à une playlist
                          </DropdownMenuSubTrigger>
                          <DropdownMenuPortal>
                            <DropdownMenuSubContent>
                              {playlistsData?.playlists.map((playlist) => (
                                <DropdownMenuItem
                                  key={playlist.id}
                                  onClick={() =>
                                    handleAddToPlaylist(playlist.id, track.id)
                                  }
                                >
                                  {playlist.title}
                                </DropdownMenuItem>
                              ))}
                            </DropdownMenuSubContent>
                          </DropdownMenuPortal>
                        </DropdownMenuSub>
                      </DropdownMenuContent>
                    </DropdownMenu>
                  </div>
                )}
              />
            )}
          </CardContent>
        </Card>
      )}

      {/* Pagination removed - using infinite scroll instead */}
      {/* Show loading indicator at bottom when fetching more */}
      {isFetchingNextPage && (
        <div className="flex justify-center items-center py-6">
          <LoadingState
            isLoading={true}
            variant="inline"
            size="sm"
            text="Chargement de plus de pistes..."
            className="text-kodo-secondary"
          />
        </div>
      )}

      {/* Show end of list indicator when all tracks loaded */}
      {!hasNextPage &&
        !isFetchingNextPage &&
        filteredTracks.length > 0 &&
        viewMode === 'list' && (
          <div className="flex justify-center items-center py-4">
            <p className="text-sm text-kodo-secondary">
              Toutes les pistes ont été chargées ({filteredTracks.length} piste
              {filteredTracks.length > 1 ? 's' : ''})
            </p>
          </div>
        )}

      {/* Show error indicator for infinite scroll errors (error after initial load) */}
      {isTracksError &&
        tracksError &&
        filteredTracks.length > 0 &&
        !isTracksLoading && (
          <div className="flex flex-col items-center justify-center py-4 gap-2">
            <p className="text-sm text-red-400">
              Erreur lors du chargement de plus de pistes
            </p>
            <Button
              variant="outline"
              size="sm"
              onClick={() => fetchNextPage()}
              className="text-xs"
            >
              Réessayer
            </Button>
          </div>
        )}

      <UploadModal open={isUploadModalOpen} onClose={handleCloseUpload} />

      <ConfirmationDialog
        open={showDeleteConfirm}
        onClose={() => setShowDeleteConfirm(false)}
        onConfirm={confirmBulkDelete}
        title="Supprimer les pistes"
        description={`Êtes-vous sûr de vouloir supprimer ${selectedTracks.size} piste(s) ? Cette action est irréversible.`}
        confirmLabel="Supprimer"
        variant="destructive"
      />
    </div>
  );
}
