import { apiClient } from '@/services/api/client';
import { Track } from '../types/track';
import { AxiosError } from 'axios';
import { TrackServiceError as TrackUploadError } from '../errors/trackErrors';

/**
 * Interface pour la réponse de likes d'un track
 */
export interface TrackLikesResponse {
  count: number;
  is_liked: boolean;
}

/**
 * Interface pour la réponse de tracks likés par un utilisateur
 */
export interface UserLikedTracksResponse {
  tracks: Track[];
  total: number;
  limit: number;
  offset: number;
}

/**
 * Like un track
 * @param trackId ID du track à liker
 * @throws Error si la requête échoue
 */
export async function likeTrack(trackId: string): Promise<void> {
  try {
    await apiClient.post(`/tracks/${trackId}/like`);
  } catch (error: unknown) {
    if (error instanceof AxiosError) {
      if (error.response?.status === 401) {
        throw new TrackUploadError(
          'Non autorisé: Veuillez vous connecter pour liker ce track',
          'VALIDATION',
          false,
          error,
        );
      }
      if (error.response?.status === 404) {
        throw new TrackUploadError(
          'Track introuvable',
          'VALIDATION',
          false,
          error,
        );
      }
      if (error.response?.status === 500) {
        throw new TrackUploadError(
          'Erreur serveur: Impossible de liker le track. Veuillez réessayer plus tard.',
          'SERVER',
          true,
          error,
        );
      }
      if (
        error.code === 'ECONNABORTED' ||
        error.code === 'ETIMEDOUT' ||
        !error.response
      ) {
        throw new TrackUploadError(
          'Erreur réseau: Impossible de se connecter au serveur.',
          'NETWORK',
          true,
          error,
        );
      }
      const errorMessage =
        error.response?.data?.error ||
        error.message ||
        'Échec du like du track';
      throw new TrackUploadError(errorMessage, 'UNKNOWN', false, error);
    }
    if (error instanceof TrackUploadError) {
      throw error;
    }
    throw new TrackUploadError(
      'Erreur inconnue lors du like du track',
      'UNKNOWN',
      false,
      error,
    );
  }
}

/**
 * Unlike un track
 * @param trackId ID du track à unliker
 * @throws Error si la requête échoue
 */
export async function unlikeTrack(trackId: string): Promise<void> {
  try {
    await apiClient.delete(`/tracks/${trackId}/like`);
  } catch (error: unknown) {
    if (error instanceof AxiosError) {
      if (error.response?.status === 401) {
        throw new TrackUploadError(
          'Non autorisé: Veuillez vous connecter pour unliker ce track',
          'VALIDATION',
          false,
          error,
        );
      }
      if (error.response?.status === 404) {
        throw new TrackUploadError(
          'Track introuvable',
          'VALIDATION',
          false,
          error,
        );
      }
      if (error.response?.status === 500) {
        throw new TrackUploadError(
          'Erreur serveur: Impossible de unliker le track. Veuillez réessayer plus tard.',
          'SERVER',
          true,
          error,
        );
      }
      if (
        error.code === 'ECONNABORTED' ||
        error.code === 'ETIMEDOUT' ||
        !error.response
      ) {
        throw new TrackUploadError(
          'Erreur réseau: Impossible de se connecter au serveur.',
          'NETWORK',
          true,
          error,
        );
      }
      const errorMessage =
        error.response?.data?.error ||
        error.message ||
        "Échec de l'unlike du track";
      throw new TrackUploadError(errorMessage, 'UNKNOWN', false, error);
    }
    if (error instanceof TrackUploadError) {
      throw error;
    }
    throw new TrackUploadError(
      "Erreur inconnue lors de l'unlike du track",
      'UNKNOWN',
      false,
      error,
    );
  }
}

/**
 * Récupère le nombre de likes et si l'utilisateur a liké un track
 * @param trackId ID du track
 * @returns Le nombre de likes et si l'utilisateur a liké
 * @throws Error si la requête échoue
 */
export async function getTrackLikes(
  trackId: string,
): Promise<{ count: number; isLiked: boolean }> {
  try {
    const response = await apiClient.get<TrackLikesResponse>(
      `/tracks/${trackId}/likes`,
    );
    return {
      count: response.data.count,
      isLiked: response.data.is_liked,
    };
  } catch (error: unknown) {
    if (error instanceof AxiosError) {
      if (error.response?.status === 404) {
        throw new TrackUploadError(
          'Track introuvable',
          'VALIDATION',
          false,
          error,
        );
      }
      if (error.response?.status === 500) {
        throw new TrackUploadError(
          'Erreur serveur: Impossible de récupérer les likes. Veuillez réessayer plus tard.',
          'SERVER',
          true,
          error,
        );
      }
      if (
        error.code === 'ECONNABORTED' ||
        error.code === 'ETIMEDOUT' ||
        !error.response
      ) {
        throw new TrackUploadError(
          'Erreur réseau: Impossible de se connecter au serveur.',
          'NETWORK',
          true,
          error,
        );
      }
      const errorMessage =
        error.response?.data?.error ||
        error.message ||
        'Échec de la récupération des likes';
      throw new TrackUploadError(errorMessage, 'UNKNOWN', false, error);
    }
    if (error instanceof TrackUploadError) {
      throw error;
    }
    throw new TrackUploadError(
      'Erreur inconnue lors de la récupération des likes',
      'UNKNOWN',
      false,
      error,
    );
  }
}

/**
 * Récupère les tracks likés par un utilisateur
 * @param userId ID de l'utilisateur
 * @param limit Nombre de tracks à récupérer (défaut: 20)
 * @param offset Offset pour la pagination (défaut: 0)
 * @returns La liste des tracks likés avec pagination
 * @throws Error si la requête échoue
 */
export async function getUserLikedTracks(
  userId: string,
  limit: number = 20,
  offset: number = 0,
): Promise<UserLikedTracksResponse> {
  try {
    const response = await apiClient.get<UserLikedTracksResponse>(
      `/users/${userId}/liked-tracks?limit=${limit}&offset=${offset}`,
    );
    return response.data;
  } catch (error: unknown) {
    if (error instanceof AxiosError) {
      if (error.response?.status === 401) {
        throw new TrackUploadError(
          'Non autorisé: Veuillez vous connecter pour voir les tracks likés',
          'VALIDATION',
          false,
          error,
        );
      }
      if (error.response?.status === 404) {
        throw new TrackUploadError(
          'Utilisateur introuvable',
          'VALIDATION',
          false,
          error,
        );
      }
      if (error.response?.status === 500) {
        throw new TrackUploadError(
          'Erreur serveur: Impossible de récupérer les tracks likés. Veuillez réessayer plus tard.',
          'SERVER',
          true,
          error,
        );
      }
      if (
        error.code === 'ECONNABORTED' ||
        error.code === 'ETIMEDOUT' ||
        !error.response
      ) {
        throw new TrackUploadError(
          'Erreur réseau: Impossible de se connecter au serveur.',
          'NETWORK',
          true,
          error,
        );
      }
      const errorMessage =
        error.response?.data?.error ||
        error.message ||
        'Échec de la récupération des tracks likés';
      throw new TrackUploadError(errorMessage, 'UNKNOWN', false, error);
    }
    if (error instanceof TrackUploadError) {
      throw error;
    }
    throw new TrackUploadError(
      'Erreur inconnue lors de la récupération des tracks likés',
      'UNKNOWN',
      false,
      error,
    );
  }
}
