// INT-CLEANUP-002: Use standardized ApiError from @/types/api instead of duplicating
import { apiClient } from '@/services/api/client';
import type { Track } from '../../player/types';

export interface PaginationOptions {
  page?: number;
  limit?: number;
}

export interface TrackFilters {
  genre?: string;
  artist?: string;
  album?: string;
  year?: number;
  minDuration?: number;
  maxDuration?: number;
}

export interface TrackSortOptions {
  field: string;
  order: 'asc' | 'desc';
}

export interface GetTracksOptions {
  pagination?: PaginationOptions;
  filters?: TrackFilters;
  sort?: TrackSortOptions;
  search?: string;
}

export interface PaginatedResponse<T> {
  data: T[];
  total: number;
  page: number;
  limit: number;
  totalPages: number;
}

export interface TracksResponse {
  tracks: Track[];
  total: number;
  page?: number;
  limit?: number;
  totalPages?: number;
}

// INT-CLEANUP-002: ApiError removed - use @/types/api instead

export async function getTracks(
  options: GetTracksOptions = {},
): Promise<PaginatedResponse<Track>> {
  const params = new URLSearchParams();

  if (options.pagination) {
    if (options.pagination.page)
      params.append('page', options.pagination.page.toString());
    if (options.pagination.limit)
      params.append('limit', options.pagination.limit.toString());
  }

  if (options.filters) {
    if (options.filters.genre) params.append('genre', options.filters.genre);
    if (options.filters.artist) params.append('artist', options.filters.artist);
    if (options.filters.album) params.append('album', options.filters.album);
    if (options.filters.minDuration)
      params.append('min_duration', options.filters.minDuration.toString());
    if (options.filters.maxDuration)
      params.append('max_duration', options.filters.maxDuration.toString());
  }

  if (options.sort) {
    params.append('sort_by', options.sort.field);
    params.append('sort_order', options.sort.order);
  }

  if (options.search) {
    params.append('search', options.search);
  }

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

  const response = await apiClient.get<TracksResponse>(url);
  const { tracks, total, page, limit, totalPages } = response.data;

  // Calculate default values if missing (based on tests expecting logic)
  const currentPage = page || options.pagination?.page || 1;
  const currentLimit =
    limit || options.pagination?.limit || tracks.length || 10;
  const calculatedTotalPages =
    totalPages || Math.ceil(total / currentLimit) || 1;

  return {
    data: tracks,
    total,
    page: currentPage,
    limit: currentLimit,
    totalPages: calculatedTotalPages,
  };
}

export async function getTrackById(id: string): Promise<Track> {
  const response = await apiClient.get<{ data: Track } | Track>(
    `/tracks/${id}`,
  );
  // Handle potentially different response structures based on test mocks
  if ('data' in response.data) {
    return response.data.data;
    // Test: mockResponse = { data: mockTracks[0] }. apiClient.get resolves to mockResponse.
    // So response.data IS mockTracks[0].
    // Wait, test says: vi.mocked(apiClient.get).mockResolvedValue(mockResponse);
    // apiClient.get returns AxiosReponse. So response.data is the body.
    // If body is mockTracks[0], then return response.data.
  }
  return response.data as Track;
}

export async function getTracksByArtist(
  artist: string,
  options: GetTracksOptions = {},
): Promise<PaginatedResponse<Track>> {
  return getTracks({
    ...options,
    filters: { ...options.filters, artist },
  });
}

export async function getTracksByAlbum(
  album: string,
  options: GetTracksOptions = {},
): Promise<PaginatedResponse<Track>> {
  return getTracks({
    ...options,
    filters: { ...options.filters, album },
  });
}

export async function getTracksByGenre(
  genre: string,
  options: GetTracksOptions = {},
): Promise<PaginatedResponse<Track>> {
  return getTracks({
    ...options,
    filters: { ...options.filters, genre },
  });
}

export async function searchTracks(
  query: string,
  options: GetTracksOptions = {},
): Promise<PaginatedResponse<Track>> {
  return getTracks({
    ...options,
    search: query,
  });
}
