/**
 * Composant modal pour ajouter des tracks à une playlist
 * T0471: Create Add Track to Playlist Component
 */

import { useState, useEffect, useCallback } from 'react';
import { useDebounce } from '@/hooks/useDebounce';
import { Modal } from '@/components/ui/modal';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Checkbox } from '@/components/ui/checkbox';
import { useToast } from '@/hooks/useToast';
import { useAddTrackToPlaylist } from '../hooks/usePlaylist';
import {
  searchTracks,
  TrackSearchError,
} from '@/features/tracks/services/trackSearchService';
import type { Track } from '@/features/tracks/types/track';
import { Search, Loader2, Plus } from 'lucide-react';
import { cn } from '@/lib/utils';
import { logger } from '@/utils/logger';

interface AddTrackToPlaylistModalProps {
  open: boolean;
  onClose: () => void;
  playlistId: string;
  onTracksAdded?: () => void;
}

export function AddTrackToPlaylistModal({
  open,
  onClose,
  playlistId,
  onTracksAdded,
}: AddTrackToPlaylistModalProps) {
  const [searchQuery, setSearchQuery] = useState('');
  // Action 2.4.1.3: Use useDebounce hook instead of manual setTimeout for consistency
  const debouncedSearchQuery = useDebounce(searchQuery, 500);
  const [tracks, setTracks] = useState<Track[]>([]);
  const [selectedTracks, setSelectedTracks] = useState<Set<string>>(new Set());
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [page, setPage] = useState(1);
  const [total, setTotal] = useState(0);
  const [addingTracks, setAddingTracks] = useState(false);

  const { success: showSuccess, error: showError } = useToast();
  const addTrackMutation = useAddTrackToPlaylist();

  const performSearch = useCallback(async () => {
    setLoading(true);
    setError(null);

    try {
      const response = await searchTracks({
        query: debouncedSearchQuery.trim() || undefined,
        page,
        limit: 20,
      });
      setTracks(response.tracks);
      setTotal(response.pagination.total);
    } catch (err) {
      let errorMessage = 'Erreur lors de la recherche';
      if (err instanceof TrackSearchError) {
        errorMessage = err.message;
      } else if (err instanceof Error) {
        errorMessage = err.message;
      }
      setError(errorMessage);
      setTracks([]);
      setTotal(0);
    } finally {
      setLoading(false);
    }
  }, [debouncedSearchQuery, page]);

  // Effectuer la recherche quand la query debounced change
  useEffect(() => {
    if (debouncedSearchQuery.trim() || open) {
      performSearch();
    } else {
      setTracks([]);
      setTotal(0);
    }
  }, [debouncedSearchQuery, open, performSearch]);

  // Réinitialiser quand le modal s'ouvre
  useEffect(() => {
    if (open) {
      setSearchQuery('');
      setSelectedTracks(new Set());
      setPage(1);
      setError(null);
    }
  }, [open]);

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

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

  const handleAddTracks = async () => {
    if (selectedTracks.size === 0) {
      showError('Aucun track sélectionné');
      return;
    }

    setAddingTracks(true);
    const trackIds = Array.from(selectedTracks);
    let successCount = 0;
    let errorCount = 0;

    try {
      // Ajouter les tracks un par un
      for (const trackId of trackIds) {
        try {
          await addTrackMutation.mutateAsync({
            playlistId, // playlistId is already string
            trackId,
          });
          successCount++;
        } catch (err) {
          errorCount++;
          logger.error(`Failed to add track ${trackId}:`, { error: err });
        }
      }

      if (successCount > 0) {
        showSuccess(
          `${successCount} track${successCount > 1 ? 's' : ''} ajouté${successCount > 1 ? 's' : ''} à la playlist.`,
        );
        setSelectedTracks(new Set());
        onTracksAdded?.();
        onClose();
      }

      if (errorCount > 0) {
        showError(
          `${errorCount} track${errorCount > 1 ? 's' : ''} n'a${errorCount > 1 ? 'ont' : ''} pas pu être ajouté${errorCount > 1 ? 's' : ''}.`,
        );
      }
    } finally {
      setAddingTracks(false);
    }
  };

  const handleClose = () => {
    setSearchQuery('');
    setSelectedTracks(new Set());
    setPage(1);
    setError(null);
    onClose();
  };

  return (
    <Modal
      open={open}
      onClose={handleClose}
      title="Ajouter des tracks à la playlist"
      size="xl"
    >
      <div className="space-y-4">
        {/* Recherche */}
        <div className="relative">
          <Search className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-muted-foreground" />
          <Input
            type="text"
            placeholder="Rechercher des tracks..."
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            className="pl-10"
          />
        </div>

        {/* Liste des tracks avec sélection */}
        <div className="border rounded-lg max-h-[400px] overflow-y-auto">
          {loading && tracks.length === 0 ? (
            <div className="flex items-center justify-center p-8">
              <Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
              <span className="ml-2 text-muted-foreground">
                Recherche en cours...
              </span>
            </div>
          ) : error ? (
            <div className="p-8 text-center text-destructive">
              <p>{error}</p>
            </div>
          ) : tracks.length === 0 ? (
            <div className="p-8 text-center text-muted-foreground">
              <p>Aucun track trouvé</p>
            </div>
          ) : (
            <>
              {/* En-tête avec sélection multiple */}
              <div className="sticky top-0 bg-background border-b p-4 flex items-center justify-between">
                <div className="flex items-center space-x-2">
                  <Checkbox
                    checked={
                      tracks.length > 0 && selectedTracks.size === tracks.length
                    }
                    onCheckedChange={handleSelectAll}
                    disabled={loading}
                  />
                  <span className="text-sm font-medium">
                    {selectedTracks.size > 0
                      ? `${selectedTracks.size} track${selectedTracks.size > 1 ? 's' : ''} sélectionné${selectedTracks.size > 1 ? 's' : ''}`
                      : 'Sélectionner tout'}
                  </span>
                </div>
                {total > 0 && (
                  <span className="text-sm text-muted-foreground">
                    {total} track{total > 1 ? 's' : ''} trouvé
                    {total > 1 ? 's' : ''}
                  </span>
                )}
              </div>

              {/* Liste des tracks */}
              <div className="divide-y">
                {tracks.map((track) => {
                  const isSelected = selectedTracks.has(track.id);
                  return (
                    <div
                      key={track.id}
                      className={cn(
                        'p-4 flex items-center space-x-4 hover:bg-muted/50 transition-colors',
                        isSelected && 'bg-muted/30',
                      )}
                    >
                      <Checkbox
                        checked={isSelected}
                        onCheckedChange={() => handleTrackToggle(track.id)}
                      />
                      <div className="flex-1 min-w-0">
                        <p className="font-medium truncate">{track.title}</p>
                        <p className="text-sm text-muted-foreground truncate">
                          {track.artist}
                          {track.album && ` • ${track.album}`}
                        </p>
                      </div>
                      <div className="text-sm text-muted-foreground">
                        {Math.floor(track.duration / 60)}:
                        {String(track.duration % 60).padStart(2, '0')}
                      </div>
                    </div>
                  );
                })}
              </div>

              {/* Pagination simple */}
              {total > 20 && (
                <div className="p-4 border-t flex items-center justify-between">
                  <span className="text-sm text-muted-foreground">
                    Page {page} sur {Math.ceil(total / 20)}
                  </span>
                  <div className="flex gap-2">
                    <Button
                      variant="outline"
                      size="sm"
                      onClick={() => setPage((p) => Math.max(1, p - 1))}
                      disabled={page === 1 || loading}
                    >
                      Précédent
                    </Button>
                    <Button
                      variant="outline"
                      size="sm"
                      onClick={() => setPage((p) => p + 1)}
                      disabled={page >= Math.ceil(total / 20) || loading}
                    >
                      Suivant
                    </Button>
                  </div>
                </div>
              )}
            </>
          )}
        </div>

        {/* Actions */}
        <div className="flex items-center justify-between pt-4 border-t">
          <span className="text-sm text-muted-foreground">
            {selectedTracks.size > 0
              ? `${selectedTracks.size} track${selectedTracks.size > 1 ? 's' : ''} sélectionné${selectedTracks.size > 1 ? 's' : ''}`
              : 'Sélectionnez des tracks à ajouter'}
          </span>
          <div className="flex gap-2">
            <Button
              variant="outline"
              onClick={handleClose}
              disabled={addingTracks}
            >
              Annuler
            </Button>
            <Button
              onClick={handleAddTracks}
              disabled={selectedTracks.size === 0 || addingTracks}
            >
              {addingTracks && (
                <Loader2 className="w-4 h-4 mr-2 animate-spin" />
              )}
              <Plus className="w-4 h-4 mr-2" />
              Ajouter {selectedTracks.size > 0 && `(${selectedTracks.size})`}
            </Button>
          </div>
        </div>
      </div>
    </Modal>
  );
}
