import { apiClient } from '@/services/api/client';
import { AxiosError } from 'axios';

/**
 * Track History Service
 * T0329: Service frontend pour récupérer l'historique des modifications de tracks
 */

/**
 * Classe d'erreur personnalisée pour l'historique de tracks
 */
export class TrackHistoryError extends Error {
  constructor(
    message: string,
    public code: 'VALIDATION' | 'NETWORK' | 'SERVER' | 'NOT_FOUND' | 'UNKNOWN',
    public retryable: boolean = false,
    public originalError?: unknown,
  ) {
    super(message);
    this.name = 'TrackHistoryError';
  }
}

/**
 * Type d'action effectuée sur un track
 */
export type TrackHistoryAction =
  | 'created'
  | 'updated'
  | 'deleted'
  | 'published'
  | 'unpublished'
  | 'restored';

/**
 * Interface pour une entrée d'historique de track
 */
export interface TrackHistory {
  id: string;
  track_id: string;
  user_id: string;
  action: TrackHistoryAction;
  old_value?: string;
  new_value?: string;
  created_at: string;
}

/**
 * Interface pour la réponse de récupération de l'historique
 */
export interface TrackHistoryResponse {
  history: TrackHistory[];
  total: number;
  limit: number;
  offset: number;
}

/**
 * Options de pagination pour la récupération de l'historique
 */
export interface TrackHistoryOptions {
  limit?: number;
  offset?: number;
}

/**
 * Récupère l'historique des modifications d'un track
 * @param trackId ID du track
 * @param options Options de pagination (limit, offset)
 * @returns L'historique du track avec pagination
 * @throws TrackHistoryError si la requête échoue
 */
export async function getTrackHistory(
  trackId: string,
  options?: TrackHistoryOptions,
): Promise<TrackHistoryResponse> {
  try {
    const params = new URLSearchParams();
    if (options?.limit !== undefined) {
      params.append('limit', options.limit.toString());
    }
    if (options?.offset !== undefined) {
      params.append('offset', options.offset.toString());
    }

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

    const response = await apiClient.get<TrackHistoryResponse>(url);
    return response.data;
  } catch (error) {
    if (error instanceof AxiosError) {
      if (error.response?.status === 400) {
        throw new TrackHistoryError(
          'Requête invalide: ID de track invalide',
          'VALIDATION',
          false,
          error,
        );
      }
      if (error.response?.status === 404) {
        throw new TrackHistoryError(
          'Track introuvable',
          'NOT_FOUND',
          false,
          error,
        );
      }
      if (error.response?.status === 500) {
        throw new TrackHistoryError(
          "Erreur serveur: Impossible de récupérer l'historique. Veuillez réessayer plus tard.",
          'SERVER',
          true,
          error,
        );
      }
      if (
        error.code === 'ECONNABORTED' ||
        error.code === 'ETIMEDOUT' ||
        !error.response
      ) {
        throw new TrackHistoryError(
          'Erreur réseau: Impossible de se connecter au serveur. Veuillez vérifier votre connexion.',
          'NETWORK',
          true,
          error,
        );
      }
      const errorMessage =
        error.response?.data?.error ||
        error.message ||
        "Échec de la récupération de l'historique";
      throw new TrackHistoryError(errorMessage, 'UNKNOWN', false, error);
    }
    if (error instanceof TrackHistoryError) {
      throw error;
    }
    throw new TrackHistoryError(
      "Erreur inconnue lors de la récupération de l'historique",
      'UNKNOWN',
      false,
      error,
    );
  }
}
