import { useState, useEffect } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { Button } from '@/components/ui/button';
import { UserPlus, UserCheck, Loader2 } from 'lucide-react';
import { cn } from '@/lib/utils';
import {
  followPlaylist,
  unfollowPlaylist,
  getPlaylist,
  getPlaylistFollowStatus,
} from '../services/playlistService';
import type { Playlist } from '../types';
import { useToast } from '@/hooks/useToast';
import { useUser } from '@/features/auth/hooks/useUser';

/**
 * FE-COMP-017: Follow/Unfollow button component for playlists
 */

interface PlaylistFollowButtonProps {
  playlistId: string;
  initialFollowing?: boolean;
  initialFollowerCount?: number;
  onFollowChange?: (isFollowing: boolean) => void;
  className?: string;
  size?: 'default' | 'sm' | 'lg' | 'icon';
  variant?: 'default' | 'outline' | 'ghost';
  showCount?: boolean;
}

export function PlaylistFollowButton({
  playlistId,
  initialFollowing = false,
  initialFollowerCount = 0,
  onFollowChange,
  className,
  size = 'default',
  variant,
  showCount = false,
}: PlaylistFollowButtonProps) {
  const { data: user } = useUser();
  const { success: showSuccess, error: showError } = useToast();
  const queryClient = useQueryClient();
  const [following, setFollowing] = useState(initialFollowing);
  const [followerCount, setFollowerCount] = useState(initialFollowerCount);
  const [isUpdating, setIsUpdating] = useState(false);

  // Fetch playlist to get current follow status
  const { data: playlist } = useQuery<Playlist>({
    queryKey: ['playlist', playlistId],
    queryFn: () => getPlaylist(playlistId),
    enabled: !!playlistId && !!user,
    staleTime: 30000, // 30 seconds
  });

  // Try to fetch follow status if available
  const { data: followStatus } = useQuery({
    queryKey: ['playlistFollowStatus', playlistId],
    queryFn: () => getPlaylistFollowStatus(playlistId),
    enabled: !!playlistId && !!user,
    staleTime: 30000,
    retry: false,
  });

  // Update state from API response
  useEffect(() => {
    if (followStatus) {
      setFollowing(followStatus.is_following);
      setFollowerCount(followStatus.follower_count);
    } else if (playlist && (playlist as any).is_following !== undefined) {
      setFollowing((playlist as any).is_following);
    } else if (initialFollowing !== undefined) {
      setFollowing(initialFollowing);
    }
    if (playlist && (playlist as any).follower_count !== undefined) {
      setFollowerCount((playlist as any).follower_count);
    } else if (initialFollowerCount !== undefined) {
      setFollowerCount(initialFollowerCount);
    }
  }, [followStatus, playlist, initialFollowing, initialFollowerCount]);

  // Follow mutation
  const followMutation = useMutation({
    mutationFn: () => followPlaylist(playlistId),
    onMutate: async () => {
      // Optimistic update
      setFollowing(true);
      setFollowerCount((prev) => prev + 1);
      setIsUpdating(true);
    },
    onSuccess: () => {
      showSuccess('Vous suivez maintenant cette playlist');
      onFollowChange?.(true);
      // Invalidate queries to refresh data
      queryClient.invalidateQueries({ queryKey: ['playlist', playlistId] });
      queryClient.invalidateQueries({
        queryKey: ['playlistFollowStatus', playlistId],
      });
      queryClient.invalidateQueries({ queryKey: ['playlists'] });
    },
    onError: (error: any) => {
      // Revert optimistic update
      setFollowing(false);
      setFollowerCount((prev) => Math.max(0, prev - 1));
      const errorMessage =
        error.response?.data?.error?.message ||
        error.response?.data?.message ||
        error.message ||
        "Erreur lors de l'abonnement à la playlist";
      showError(errorMessage);
    },
    onSettled: () => {
      setIsUpdating(false);
    },
  });

  // Unfollow mutation
  const unfollowMutation = useMutation({
    mutationFn: () => unfollowPlaylist(playlistId),
    onMutate: async () => {
      // Optimistic update
      setFollowing(false);
      setFollowerCount((prev) => Math.max(0, prev - 1));
      setIsUpdating(true);
    },
    onSuccess: () => {
      showSuccess('Vous ne suivez plus cette playlist');
      onFollowChange?.(false);
      // Invalidate queries to refresh data
      queryClient.invalidateQueries({ queryKey: ['playlist', playlistId] });
      queryClient.invalidateQueries({
        queryKey: ['playlistFollowStatus', playlistId],
      });
      queryClient.invalidateQueries({ queryKey: ['playlists'] });
    },
    onError: (error: any) => {
      // Revert optimistic update
      setFollowing(true);
      setFollowerCount((prev) => prev + 1);
      const errorMessage =
        error.response?.data?.error?.message ||
        error.response?.data?.message ||
        error.message ||
        'Erreur lors du désabonnement de la playlist';
      showError(errorMessage);
    },
    onSettled: () => {
      setIsUpdating(false);
    },
  });

  const handleClick = (e: React.MouseEvent) => {
    e.stopPropagation();
    if (isUpdating || !user) return;

    if (following) {
      unfollowMutation.mutate();
    } else {
      followMutation.mutate();
    }
  };

  // Don't show follow button if user is not logged in or is the owner
  if (!user || user.id === playlist?.user_id) {
    return null;
  }

  const isLoading =
    followMutation.isPending || unfollowMutation.isPending || isUpdating;
  const buttonVariant = variant || (following ? 'outline' : 'default');

  return (
    <Button
      onClick={handleClick}
      disabled={isLoading}
      variant={buttonVariant}
      size={size}
      className={cn(className, 'min-w-[100px]')}
    >
      {isLoading ? (
        <>
          <Loader2 className="h-4 w-4 animate-spin mr-2" />
          {following ? 'Désabonnement...' : 'Abonnement...'}
        </>
      ) : following ? (
        <>
          <UserCheck className="h-4 w-4 mr-2" />
          Abonné
          {showCount && followerCount > 0 && (
            <span className="ml-2 text-xs">({followerCount})</span>
          )}
        </>
      ) : (
        <>
          <UserPlus className="h-4 w-4 mr-2" />
          Suivre
          {showCount && followerCount > 0 && (
            <span className="ml-2 text-xs">({followerCount})</span>
          )}
        </>
      )}
    </Button>
  );
}
