/**
 * Composant PlaylistList
 * T0459: Create Playlist List Component
 */

import { useState, useMemo } from 'react';
import { useQuery } from '@tanstack/react-query';
import { usePlaylists } from '../hooks/usePlaylist';
import { playlistsApi } from '@/services/api/playlists';
import { useUser } from '@/features/auth/hooks/useUser';
import { PlaylistCard } from './PlaylistCard';
import { PlaylistListSkeleton } from './PlaylistListSkeleton';
import { PlaylistBatchActions } from './PlaylistBatchActions';
import { Button } from '@/components/ui/button';
import { List, Grid, CheckSquare, Square, Library } from 'lucide-react';
import { cn } from '@/lib/utils';
import { Pagination } from '@/components/navigation/Pagination';
import type { Playlist } from '../types';

// FE-PAGE-009: Complete Playlist List page implementation

type SortField = 'created_at' | 'title' | 'track_count';
type SortOrder = 'asc' | 'desc';

interface PlaylistListProps {
  view?: 'grid' | 'list';
  limit?: number;
  className?: string;
  enableSelection?: boolean;
  searchQuery?: string;
  filterIsPublic?: boolean;
  filterOwner?: 'all' | 'mine' | 'others';
  sortBy?: SortField;
  sortOrder?: SortOrder;
}

export function PlaylistList({
  view: initialView = 'grid',
  limit = 20,
  className,
  enableSelection = false,
  searchQuery = '',
  filterIsPublic,
  filterOwner = 'all',
  sortBy = 'created_at',
  sortOrder = 'desc',
}: PlaylistListProps) {
  const [currentView, setCurrentView] = useState<'grid' | 'list'>(initialView);
  const [offset, setOffset] = useState(0);
  const [selectedPlaylists, setSelectedPlaylists] = useState<Set<string>>(
    new Set(),
  );
  const { data: user } = useUser();
  const page = Math.floor(offset / limit) + 1;

  // FE-PAGE-009: Use search API when search query or filters are active
  const hasSearchOrFilters = !!(
    searchQuery.trim() ||
    filterIsPublic !== undefined ||
    filterOwner !== 'all'
  );

  // CRITIQUE FIX #45: Passer les paramètres de tri au backend
  // Le backend peut ignorer ces paramètres s'il ne les supporte pas encore
  // Cela permet une migration facile vers le tri backend quand il sera disponible
  const {
    data: searchData,
    isLoading: isSearchLoading,
    error: searchError,
  } = useQuery({
    queryKey: [
      'playlistSearch',
      searchQuery,
      filterIsPublic,
      filterOwner,
      page,
      limit,
      sortBy,
      sortOrder,
    ],
    queryFn: () =>
      playlistsApi.search({
        q: searchQuery.trim() || undefined,
        page,
        limit,
        is_public: filterIsPublic,
        user_id: filterOwner === 'mine' && user?.id ? user.id : undefined,
        sort_by: sortBy,
        sort_order: sortOrder,
      }),
    enabled: hasSearchOrFilters,
  });

  const {
    data: listData,
    isLoading: isListLoading,
    error: listError,
  } = usePlaylists(limit, offset, sortBy, sortOrder);

  // Use search results if search/filters are active, otherwise use list
  const data = hasSearchOrFilters ? searchData : listData;
  const isLoading = hasSearchOrFilters ? isSearchLoading : isListLoading;
  const error = hasSearchOrFilters ? searchError : listError;

  // CRITIQUE FIX #45: Tri côté client temporaire jusqu'à ce que le backend supporte le tri
  // Les paramètres de tri sont maintenant passés au backend, mais on fait toujours le tri côté client
  // comme fallback jusqu'à ce que le backend les supporte
  // TODO: Retirer ce tri côté client une fois que le backend supporte le tri
  const sortedPlaylists = useMemo(() => {
    const playlists = data?.playlists || [];
    if (playlists.length === 0) return [];

    // Si le backend retourne déjà les données triées (détecté par la présence de sort_by dans la réponse),
    // on peut utiliser directement les données sans trier
    // Pour l'instant, on trie toujours côté client comme fallback
    const sorted = [...playlists];
    return sorted.sort((a, b) => {
      let comparison = 0;
      switch (sortBy) {
        case 'title':
          comparison = (a.title || '').localeCompare(b.title || '');
          break;
        case 'track_count':
          comparison = (a.track_count || 0) - (b.track_count || 0);
          break;
        case 'created_at':
        default:
          comparison =
            new Date(a.created_at).getTime() - new Date(b.created_at).getTime();
          break;
      }
      return sortOrder === 'asc' ? comparison : -comparison;
    });
  }, [data?.playlists, sortBy, sortOrder]);

  const filteredPlaylists = sortedPlaylists;

  const handlePageChange = (page: number) => {
    setOffset((page - 1) * limit);
  };

  const totalPages = data ? Math.ceil(data.total / limit) : 0;
  const currentPage = data ? Math.floor(offset / limit) + 1 : 1;

  // Gestion de la sélection
  const handlePlaylistSelect = (playlist: Playlist, selected: boolean) => {
    setSelectedPlaylists((prev) => {
      const newSet = new Set(prev);
      if (selected) {
        newSet.add(playlist.id);
      } else {
        newSet.delete(playlist.id);
      }
      return newSet;
    });
  };

  const handleSelectAll = () => {
    if (!data) return;
    const allSelected = filteredPlaylists.every((p) =>
      selectedPlaylists.has(p.id),
    );
    if (allSelected) {
      setSelectedPlaylists(new Set());
    } else {
      setSelectedPlaylists(new Set(filteredPlaylists.map((p) => p.id)));
    }
  };

  const handleClearSelection = () => {
    setSelectedPlaylists(new Set());
  };

  const selectedPlaylistsArray =
    filteredPlaylists.filter((p) => selectedPlaylists.has(p.id)) || [];
  const isAllSelected =
    data &&
    filteredPlaylists.length > 0 &&
    filteredPlaylists.every((p) => selectedPlaylists.has(p.id));

  if (isLoading && !data) {
    return (
      <div
        className={cn('space-y-4', className)}
        role="region"
        aria-live="polite"
      >
        <PlaylistListSkeleton count={limit} view={currentView} />
      </div>
    );
  }

  if (error) {
    return (
      <div className={cn('text-center py-12', className)} role="alert">
        <p className="text-destructive">
          Erreur lors du chargement des playlists
        </p>
        {error instanceof Error && (
          <p className="text-sm text-muted-foreground mt-2">{error.message}</p>
        )}
      </div>
    );
  }

  if (!isLoading && !data?.playlists.length && !hasSearchOrFilters) {
    return (
      <div
        className={cn('text-center py-12', className)}
        role="region"
        aria-live="polite"
      >
        <Library className="h-12 w-12 mx-auto mb-4 text-muted-foreground opacity-50" />
        <h3 className="text-lg font-semibold mb-2">No playlists yet</h3>
        <p className="text-muted-foreground">
          Start by creating your first playlist to organize your tracks.
        </p>
      </div>
    );
  }

  // Si recherche active et aucun résultat trouvé (après filtrage)
  if (searchQuery && filteredPlaylists.length === 0) {
    return (
      <div
        className={cn('text-center py-12', className)}
        role="region"
        aria-live="polite"
      >
        <Library className="h-12 w-12 mx-auto mb-4 text-muted-foreground opacity-50" />
        <h3 className="text-lg font-semibold mb-2">No playlists found</h3>
        <p className="text-muted-foreground mb-4">
          No playlists match your search criteria. Try adjusting your filters or
          search terms.
        </p>
      </div>
    );
  }

  // Si aucune playlist (sans recherche)
  if (!isLoading && filteredPlaylists.length === 0 && !searchQuery) {
    return (
      <div
        className={cn('text-center py-12', className)}
        role="region"
        aria-live="polite"
      >
        <Library className="h-12 w-12 mx-auto mb-4 text-muted-foreground opacity-50" />
        <h3 className="text-lg font-semibold mb-2">No playlists yet</h3>
        <p className="text-muted-foreground">
          Start by creating your first playlist to organize your tracks.
        </p>
      </div>
    );
  }

  return (
    <div
      className={cn('space-y-4', className)}
      role="region"
      aria-label="Liste des playlists"
    >
      {/* Batch Actions */}
      {enableSelection && selectedPlaylists.size > 0 && (
        <PlaylistBatchActions
          selectedPlaylists={selectedPlaylistsArray}
          onSelectionClear={handleClearSelection}
        />
      )}

      {/* Toolbar: Selection toggle and View toggle */}
      <div className="flex justify-between items-center gap-2">
        {/* Select All - Only shown when selection is enabled */}
        {enableSelection && filteredPlaylists.length > 0 && (
          <Button
            variant="outline"
            size="sm"
            onClick={handleSelectAll}
            className="touch-manipulation min-h-[44px] sm:min-h-0"
            aria-label={
              isAllSelected ? 'Désélectionner toutes' : 'Sélectionner toutes'
            }
          >
            {isAllSelected ? (
              <CheckSquare className="h-4 w-4 sm:mr-2" aria-hidden="true" />
            ) : (
              <Square className="h-4 w-4 sm:mr-2" aria-hidden="true" />
            )}
            <span className="hidden sm:inline">
              {isAllSelected ? 'Tout désélectionner' : 'Tout sélectionner'}
            </span>
          </Button>
        )}

        {/* View Toggle - Hidden on mobile, shown on tablet+ */}
        <div className="hidden sm:flex justify-end items-center gap-2 ml-auto">
          <div
            className="inline-flex items-center gap-1 p-1 rounded-lg bg-gray-100 dark:bg-gray-800 border border-gray-200 dark:border-gray-700"
            role="group"
            aria-label="Changer l'affichage des playlists"
          >
            <button
              type="button"
              onClick={() => setCurrentView('list')}
              className={cn(
                'flex items-center gap-2 px-3 py-1.5 rounded-md text-sm font-medium transition-all duration-200',
                'hover:bg-gray-200 dark:hover:bg-gray-700',
                'focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2',
                'touch-manipulation', // Optimize touch response
                currentView === 'list'
                  ? 'bg-white dark:bg-gray-700 text-blue-600 dark:text-blue-400 shadow-sm'
                  : 'text-gray-600 dark:text-gray-400',
              )}
              aria-label="Affichage en liste"
              aria-pressed={currentView === 'list'}
            >
              <List className="h-4 w-4" aria-hidden="true" />
              <span className="hidden md:inline">Liste</span>
            </button>
            <button
              type="button"
              onClick={() => setCurrentView('grid')}
              className={cn(
                'flex items-center gap-2 px-3 py-1.5 rounded-md text-sm font-medium transition-all duration-200',
                'hover:bg-gray-200 dark:hover:bg-gray-700',
                'focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2',
                'touch-manipulation', // Optimize touch response
                currentView === 'grid'
                  ? 'bg-white dark:bg-gray-700 text-blue-600 dark:text-blue-400 shadow-sm'
                  : 'text-gray-600 dark:text-gray-400',
              )}
              aria-label="Affichage en grille"
              aria-pressed={currentView === 'grid'}
            >
              <Grid className="h-4 w-4" aria-hidden="true" />
              <span className="hidden md:inline">Grille</span>
            </button>
          </div>
        </div>
      </div>

      {/* Playlist List/Grid - Mobile optimized */}
      <div
        className={cn(
          currentView === 'grid'
            ? 'grid grid-cols-2 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-3 sm:gap-4'
            : 'flex flex-col gap-2 sm:gap-3',
        )}
        role="list"
        aria-label="Playlists disponibles"
      >
        {filteredPlaylists.map((playlist: Playlist) => (
          <PlaylistCard
            key={playlist.id}
            playlist={playlist}
            className={currentView === 'list' ? 'flex-row' : ''}
            selectable={enableSelection}
            selected={selectedPlaylists.has(playlist.id)}
            onSelect={handlePlaylistSelect}
          />
        ))}
        {/* Show skeleton while loading more */}
        {isLoading && <PlaylistListSkeleton count={4} view={currentView} />}
      </div>

      {/* FE-COMP-006: Pagination component */}
      {totalPages > 1 && (
        <Pagination
          currentPage={currentPage}
          totalPages={totalPages}
          onPageChange={handlePageChange}
          totalItems={data?.total || 0}
          itemsPerPage={limit}
          showItemsInfo={true}
          className="pt-4 border-t"
        />
      )}
    </div>
  );
}
