import { useState, useEffect } from 'react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog';
import { apiService, type Playlist, type Track } from '@/services/api';
import { useToast } from '@/hooks/use-toast';
import { 
  Loader2,
  Plus,
  Trash2,
  GripVertical,
  Music,
  Search,
  Clock
} from 'lucide-react';

interface PlaylistEditorProps {
  playlistId: string;
  onClose?: () => void;
}

export function PlaylistEditor({ playlistId, onClose }: PlaylistEditorProps) {
  const [playlist, setPlaylist] = useState<Playlist | null>(null);
  const [availableTracks, setAvailableTracks] = useState<Track[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [isAddDialogOpen, setIsAddDialogOpen] = useState(false);
  const [searchQuery, setSearchQuery] = useState('');
  const [isDragging, setIsDragging] = useState(false);
  const [draggedIndex, setDraggedIndex] = useState<number | null>(null);
  const { toast } = useToast();

  useEffect(() => {
    fetchPlaylistDetails();
    fetchAvailableTracks();
  }, [playlistId]);

  const fetchPlaylistDetails = async () => {
    try {
      setIsLoading(true);
      const data = await apiService.getPlaylist(playlistId);
      setPlaylist(data);
    } catch (error: any) {
      toast({
        title: 'Error',
        description: error.response?.data?.error || 'Failed to load playlist',
        variant: 'destructive',
      });
    } finally {
      setIsLoading(false);
    }
  };

  const fetchAvailableTracks = async () => {
    try {
      const response = await apiService.getTracks({ limit: 100 });
      setAvailableTracks(response.tracks);
    } catch (error: any) {
      console.error('Failed to fetch tracks:', error);
    }
  };

  const handleAddTrack = async (trackId: string) => {
    if (!playlist) return;

    try {
      const position = playlist.tracks?.length || 0;
      await apiService.addTrackToPlaylist(playlistId, trackId, position);
      
      toast({
        title: 'Track added',
        description: 'Track has been added to the playlist.',
      });
      
      fetchPlaylistDetails();
      setIsAddDialogOpen(false);
    } catch (error: any) {
      toast({
        title: 'Error',
        description: error.response?.data?.error || 'Failed to add track',
        variant: 'destructive',
      });
    }
  };

  const handleRemoveTrack = async (trackId: string) => {
    if (!playlist) return;

    try {
      await apiService.removeTrackFromPlaylist(playlistId, trackId);
      
      toast({
        title: 'Track removed',
        description: 'Track has been removed from the playlist.',
      });
      
      fetchPlaylistDetails();
    } catch (error: any) {
      toast({
        title: 'Error',
        description: error.response?.data?.error || 'Failed to remove track',
        variant: 'destructive',
      });
    }
  };

  const handleDragStart = (index: number) => {
    setIsDragging(true);
    setDraggedIndex(index);
  };

  const handleDragOver = (e: React.DragEvent, index: number) => {
    e.preventDefault();
    if (draggedIndex === null || draggedIndex === index) return;

    // TODO: Implement visual feedback for drag position
  };

  const handleDrop = async (e: React.DragEvent, dropIndex: number) => {
    e.preventDefault();
    if (draggedIndex === null || draggedIndex === dropIndex || !playlist?.tracks) return;

    // Create new tracks array with reordered items
    const newTracks = [...playlist.tracks];
    const [draggedTrack] = newTracks.splice(draggedIndex, 1);
    newTracks.splice(dropIndex, 0, draggedTrack);

    // Update positions
    for (let i = 0; i < newTracks.length; i++) {
      if (newTracks[i].position !== i) {
        // In a real implementation, you'd call an API to update positions
        // For now, we'll just update locally
        newTracks[i].position = i;
      }
    }

    setPlaylist({ ...playlist, tracks: newTracks });
    setIsDragging(false);
    setDraggedIndex(null);

    toast({
      title: 'Order updated',
      description: 'Playlist track order has been updated.',
    });
  };

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

  const filteredTracks = availableTracks.filter(track => {
    const alreadyInPlaylist = playlist?.tracks?.some(pt => pt.trackId === track.id);
    if (alreadyInPlaylist) return false;
    
    const matchesSearch = track.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
                         track.artist.toLowerCase().includes(searchQuery.toLowerCase());
    return matchesSearch;
  });

  if (isLoading) {
    return (
      <div className="flex items-center justify-center p-8">
        <Loader2 className="h-8 w-8 animate-spin" />
      </div>
    );
  }

  if (!playlist) {
    return (
      <Card>
        <CardContent className="pt-6">
          <div className="text-center text-red-500">
            Playlist not found
          </div>
        </CardContent>
      </Card>
    );
  }

  return (
    <div className="space-y-6">
      {/* Playlist Header */}
      <Card>
        <CardHeader>
          <div className="flex items-center justify-between">
            <div>
              <CardTitle>{playlist.name}</CardTitle>
              <CardDescription>
                {playlist.description || 'No description'}
              </CardDescription>
            </div>
            
            <Dialog open={isAddDialogOpen} onOpenChange={setIsAddDialogOpen}>
              <DialogTrigger asChild>
                <Button>
                  <Plus className="h-4 w-4 mr-2" />
                  Add Tracks
                </Button>
              </DialogTrigger>
              <DialogContent className="max-w-2xl">
                <DialogHeader>
                  <DialogTitle>Add Tracks to Playlist</DialogTitle>
                  <DialogDescription>
                    Select tracks from your library to add
                  </DialogDescription>
                </DialogHeader>
                
                <div className="space-y-4 py-4">
                  <div className="relative">
                    <Search className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-muted-foreground" />
                    <Input
                      placeholder="Search tracks..."
                      value={searchQuery}
                      onChange={(e) => setSearchQuery(e.target.value)}
                      className="pl-10"
                    />
                  </div>
                  
                  <div className="max-h-96 overflow-y-auto space-y-2">
                    {filteredTracks.length === 0 ? (
                      <div className="text-center py-8 text-muted-foreground">
                        {searchQuery ? 'No tracks match your search' : 'All tracks are already in this playlist'}
                      </div>
                    ) : (
                      filteredTracks.map((track) => (
                        <div
                          key={track.id}
                          className="flex items-center justify-between p-3 border rounded-lg hover:bg-muted/50 transition-colors"
                        >
                          <div className="flex items-center space-x-3 flex-1 min-w-0">
                            <Music className="h-5 w-5 text-muted-foreground flex-shrink-0" />
                            <div className="min-w-0">
                              <div className="font-medium truncate">{track.title}</div>
                              <div className="text-sm text-muted-foreground truncate">{track.artist}</div>
                            </div>
                          </div>
                          <Button
                            size="sm"
                            onClick={() => handleAddTrack(track.id)}
                          >
                            <Plus className="h-4 w-4" />
                          </Button>
                        </div>
                      ))
                    )}
                  </div>
                </div>
              </DialogContent>
            </Dialog>
          </div>
        </CardHeader>
      </Card>

      {/* Playlist Tracks */}
      <Card>
        <CardHeader>
          <CardTitle>Tracks ({playlist.tracks?.length || 0})</CardTitle>
          <CardDescription>
            Drag and drop to reorder tracks
          </CardDescription>
        </CardHeader>
        <CardContent>
          {!playlist.tracks || playlist.tracks.length === 0 ? (
            <div className="text-center py-8">
              <Music className="h-12 w-12 mx-auto text-muted-foreground mb-4" />
              <h3 className="text-lg font-medium mb-2">No tracks yet</h3>
              <p className="text-muted-foreground mb-4">
                Start adding tracks to your playlist
              </p>
              <Button onClick={() => setIsAddDialogOpen(true)}>
                <Plus className="h-4 w-4 mr-2" />
                Add Tracks
              </Button>
            </div>
          ) : (
            <div className="space-y-2">
              {playlist.tracks
                .sort((a, b) => a.position - b.position)
                .map((playlistTrack, index) => {
                  const track = playlistTrack.track;
                  if (!track) return null;

                  return (
                    <div
                      key={playlistTrack.trackId}
                      draggable
                      onDragStart={() => handleDragStart(index)}
                      onDragOver={(e) => handleDragOver(e, index)}
                      onDrop={(e) => handleDrop(e, index)}
                      className={`
                        flex items-center space-x-3 p-3 border rounded-lg 
                        hover:bg-muted/50 transition-colors cursor-move
                        ${isDragging && draggedIndex === index ? 'opacity-50' : ''}
                      `}
                    >
                      <GripVertical className="h-5 w-5 text-muted-foreground flex-shrink-0" />
                      <div className="w-8 text-sm text-muted-foreground">{index + 1}</div>
                      <Music className="h-5 w-5 text-muted-foreground flex-shrink-0" />
                      <div className="flex-1 min-w-0">
                        <div className="font-medium truncate">{track.title}</div>
                        <div className="text-sm text-muted-foreground truncate">{track.artist}</div>
                      </div>
                      {track.duration && (
                        <div className="flex items-center text-sm text-muted-foreground">
                          <Clock className="h-4 w-4 mr-1" />
                          {formatDuration(track.duration)}
                        </div>
                      )}
                      <Button
                        size="sm"
                        variant="ghost"
                        onClick={() => handleRemoveTrack(playlistTrack.trackId)}
                      >
                        <Trash2 className="h-4 w-4" />
                      </Button>
                    </div>
                  );
                })}
            </div>
          )}
        </CardContent>
      </Card>

      {/* Playlist Stats */}
      <Card>
        <CardContent className="pt-6">
          <div className="grid grid-cols-3 gap-4 text-center">
            <div>
              <div className="text-2xl font-bold">{playlist.tracks?.length || 0}</div>
              <div className="text-sm text-muted-foreground">Tracks</div>
            </div>
            <div>
              <div className="text-2xl font-bold">
                {Math.round((playlist.tracks?.reduce((sum, pt) => sum + (pt.track?.duration || 0), 0) || 0) / 60)}m
              </div>
              <div className="text-sm text-muted-foreground">Total Duration</div>
            </div>
            <div>
              <div className="text-2xl font-bold">
                <Badge variant={playlist.isPublic ? 'default' : 'secondary'}>
                  {playlist.isPublic ? 'Public' : 'Private'}
                </Badge>
              </div>
              <div className="text-sm text-muted-foreground">Visibility</div>
            </div>
          </div>
        </CardContent>
      </Card>
    </div>
  );
}

