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

/**
 * Interface pour les paramètres de liste des tracks
 */
export interface TrackListParams {
  page?: number;
  limit?: number;
  userId?: string;
  genre?: string;
  format?: string;
  sortBy?: 'created_at' | 'title' | 'popularity';
  sortOrder?: 'asc' | 'desc';
}

/**
 * Interface pour la réponse de liste des tracks
 */
export interface TrackListResponse {
  tracks: Track[];
  pagination: {
    page: number;
    limit: number;
    total: number;
    total_pages: number;
  };
  // Champs dépréciés pour rétrocompatibilité
  page: number;
  limit: number;
  total: number;
  total_pages: number;
}

/**
 * Récupère la liste des tracks
 * @param params Paramètres de filtrage et pagination
 * @returns La liste des tracks et les infos de pagination
 * @throws Error si la requête échoue
 */
export async function getTracks(
  params: TrackListParams = {},
): Promise<TrackListResponse> {
  try {
    const queryParams = new URLSearchParams();
    if (params.page) queryParams.append('page', params.page.toString());
    if (params.limit) queryParams.append('limit', params.limit.toString());
    if (params.userId) queryParams.append('user_id', params.userId);
    if (params.genre) queryParams.append('genre', params.genre);
    if (params.format) queryParams.append('format', params.format);
    if (params.sortBy) queryParams.append('sort_by', params.sortBy);
    if (params.sortOrder) queryParams.append('sort_order', params.sortOrder);

    const queryString = queryParams.toString();
    const url = `/tracks${queryString ? `?${queryString}` : ''}`;

    const response = await apiClient.get<TrackListResponse>(url);
    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',
          'VALIDATION',
          false,
          error,
        );
      }
      if (error.response?.status === 500) {
        throw new TrackUploadError(
          'Erreur serveur: Impossible de récupérer les tracks. Veuillez réessayer plus tard.',
          'SERVER',
          true,
          error,
        );
      }
      // Erreurs réseau
      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';
      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',
      'UNKNOWN',
      false,
      error,
    );
  }
}

/**
 * Récupère les détails d'un track
 * @param id ID du track
 * @returns Le track
 * @throws Error si la requête échoue
 */
export async function getTrack(id: string): Promise<Track> {
  try {
    const response = await apiClient.get<{ track: Track }>(`/tracks/${id}`);
    return response.data.track;
  } catch (error: unknown) {
    if (error instanceof AxiosError) {
      if (error.response?.status === 401) {
        throw new TrackUploadError(
          'Non autorisé: Veuillez vous connecter pour voir 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 récupérer le track. Veuillez réessayer plus tard.',
          'SERVER',
          true,
          error,
        );
      }
      // Erreurs réseau
      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 du track';
      throw new TrackUploadError(errorMessage, 'UNKNOWN', false, error);
    }
    if (error instanceof TrackUploadError) {
      throw error;
    }
    throw new TrackUploadError(
      'Erreur inconnue lors de la récupération du track',
      'UNKNOWN',
      false,
      error,
    );
  }
}

/**
 * Interface pour les paramètres de mise à jour d'un track
 */
export interface UpdateTrackParams {
  title?: string;
  description?: string;
  artist?: string;
  album?: string;
  genre?: string;
  year?: number;
  is_public?: boolean;
}

/**
 * Met à jour les métadonnées d'un track
 * @param id ID du track
 * @param params Paramètres de mise à jour
 * @returns Le track mis à jour
 * @throws Error si la requête échoue
 */
export async function updateTrack(
  id: string,
  params: UpdateTrackParams,
): Promise<Track> {
  try {
    const response = await apiClient.put<{ track: Track }>(
      `/tracks/${id}`,
      params,
    );
    return response.data.track;
  } catch (error: unknown) {
    if (error instanceof AxiosError) {
      if (error.response?.status === 401) {
        throw new TrackUploadError(
          'Non autorisé: Veuillez vous connecter pour modifier ce track',
          'VALIDATION',
          false,
          error,
        );
      }
      if (error.response?.status === 403) {
        throw new TrackUploadError(
          'Accès refusé: Vous ne pouvez modifier que vos propres tracks',
          'VALIDATION',
          false,
          error,
        );
      }
      if (error.response?.status === 404) {
        throw new TrackUploadError(
          'Track introuvable',
          'VALIDATION',
          false,
          error,
        );
      }
      if (error.response?.status === 400) {
        const errorMessage = error.response?.data?.error || 'Données invalides';
        throw new TrackUploadError(errorMessage, 'VALIDATION', false, error);
      }
      if (error.response?.status === 500) {
        throw new TrackUploadError(
          'Erreur serveur: Impossible de mettre à jour le track. Veuillez réessayer plus tard.',
          'SERVER',
          true,
          error,
        );
      }
      // Erreurs réseau
      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 mise à jour du track';
      throw new TrackUploadError(errorMessage, 'UNKNOWN', false, error);
    }
    if (error instanceof TrackUploadError) {
      throw error;
    }
    throw new TrackUploadError(
      'Erreur inconnue lors de la mise à jour du track',
      'UNKNOWN',
      false,
      error,
    );
  }
}

/**
 * Supprime un track
 * @param id ID du track à supprimer
 * @throws Error si la requête échoue
 */
export async function deleteTrack(id: string): Promise<void> {
  try {
    await apiClient.delete(`/tracks/${id}`);
  } catch (error: unknown) {
    if (error instanceof AxiosError) {
      if (error.response?.status === 401) {
        throw new TrackUploadError(
          'Non autorisé: Veuillez vous connecter pour supprimer ce track',
          'VALIDATION',
          false,
          error,
        );
      }
      if (error.response?.status === 403) {
        throw new TrackUploadError(
          'Accès refusé: Vous ne pouvez supprimer que vos propres tracks',
          '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 supprimer le track. Veuillez réessayer plus tard.',
          'SERVER',
          true,
          error,
        );
      }
      // Erreurs réseau
      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 suppression du track';
      throw new TrackUploadError(errorMessage, 'UNKNOWN', false, error);
    }
    if (error instanceof TrackUploadError) {
      throw error;
    }
    throw new TrackUploadError(
      'Erreur inconnue lors de la suppression du track',
      'UNKNOWN',
      false,
      error,
    );
  }
}
