import { apiClient } from '@/services/api/client';
import { requireFeature } from '@/config/features';
import type {
  Playlist,
  CreatePlaylistRequest,
  UpdatePlaylistRequest,
} from '../types';
import type { PlaylistListResponse } from '../types';

// Re-export PlaylistListResponse for use in other modules
export type { PlaylistListResponse } from '../types';

// Collaborator interfaces (assuming they might be in types/collaborator but defining here if needed or using any for now if not in types.ts)
// types.ts content I saw above did NOT include Collaborator types.
// I will define them here or assume they are returned as any/object for now, or add to types.ts later.
// usePlaylist.test.tsx used { id, playlist_id, user_id, permission, user: {...} }
export interface PlaylistCollaborator {
  id: string; // or number? test used number. But if we move to string... I'll use string to be safe or number if DB uses number? Tracks used string.
  playlist_id: string;
  user_id: string;
  permission: 'read' | 'write' | 'admin';
  created_at: string;
  updated_at: string;
  user: {
    id: string;
    username: string;
    email: string;
    avatar_url?: string;
  };
}

export interface AddCollaboratorRequest {
  user_id: string;
  permission: 'read' | 'write' | 'admin';
}

export interface UpdateCollaboratorPermissionRequest {
  permission: 'read' | 'write' | 'admin';
}

/**
 * Créer une nouvelle playlist
 */
export async function createPlaylist(
  data: CreatePlaylistRequest,
): Promise<Playlist> {
  const response = await apiClient.post<{ playlist: Playlist }>(
    '/playlists',
    data,
  );
  return response.data.playlist;
}

/**
 * Récupérer une playlist par ID
 */
export async function getPlaylist(id: string): Promise<Playlist> {
  const response = await apiClient.get<{ playlist: Playlist }>(
    `/playlists/${id}`,
  );
  return response.data.playlist;
}

/**
 * Mettre à jour une playlist
 */
export async function updatePlaylist(
  id: string,
  data: UpdatePlaylistRequest,
): Promise<Playlist> {
  const response = await apiClient.put<{ playlist: Playlist }>(
    `/playlists/${id}`,
    data,
  );
  return response.data.playlist;
}

/**
 * Supprimer une playlist
 */
export async function deletePlaylist(id: string): Promise<void> {
  await apiClient.delete(`/playlists/${id}`);
}

/**
 * Lister les playlists
 */
export async function listPlaylists(
  page = 1,
  limit = 20,
  userId?: string,
  sortBy?: 'created_at' | 'title' | 'track_count',
  sortOrder?: 'asc' | 'desc',
): Promise<PlaylistListResponse> {
  // S'assurer que limit n'est jamais 0 (corrige le bug GET /api/v1/playlists?page=20&limit=0: 401)
  const safeLimit = Math.max(limit, 1);
  const safePage = Math.max(page, 1);

  const params: Record<string, string | number> = {
    page: safePage,
    limit: safeLimit,
  };
  if (userId) {
    params.user_id = userId;
  }
  // CRITIQUE FIX #45: Ajouter les paramètres de tri pour préparer la migration vers le tri backend
  // Le backend peut ignorer ces paramètres s'il ne les supporte pas encore
  if (sortBy) {
    params.sort_by = sortBy;
  }
  if (sortOrder) {
    params.sort_order = sortOrder;
  }
  const response = await apiClient.get<PlaylistListResponse>('/playlists', {
    params,
  });
  return response.data;
}

/**
 * Ajouter un collaborateur à une playlist
 *
 * Backend endpoint: POST /playlists/:id/collaborators
 *
 * @see FEATURES.PLAYLIST_COLLABORATION
 */
export async function addCollaborator(
  playlistId: string,
  data: AddCollaboratorRequest,
): Promise<PlaylistCollaborator> {
  // apiClient unwraps { success, data } format automatically
  const response = await apiClient.post<PlaylistCollaborator>(
    `/playlists/${playlistId}/collaborators`,
    data,
  );
  return response.data;
}

/**
 * Retirer un collaborateur
 *
 * Backend endpoint: DELETE /playlists/:id/collaborators/:userId
 *
 * @see FEATURES.PLAYLIST_COLLABORATION
 */
export async function removeCollaborator(
  playlistId: string,
  userId: string,
): Promise<void> {
  await apiClient.delete(`/playlists/${playlistId}/collaborators/${userId}`);
}

/**
 * Mettre à jour les permissions d'un collaborateur
 *
 * Backend endpoint: PUT /playlists/:id/collaborators/:userId
 *
 * @see FEATURES.PLAYLIST_COLLABORATION
 */
export async function updateCollaboratorPermission(
  playlistId: string,
  userId: string,
  data: UpdateCollaboratorPermissionRequest,
): Promise<void> {
  await apiClient.put(`/playlists/${playlistId}/collaborators/${userId}`, data);
}

export interface SearchPlaylistsParams {
  q?: string;
  page?: number;
  limit?: number;
  user_id?: string;
  is_public?: boolean;
  sort_by?: 'created_at' | 'title' | 'track_count';
  sort_order?: 'asc' | 'desc';
}

export interface PlaylistShareLink {
  share_token: string;
  expires_at: string;
}

export interface ReorderTracksRequest {
  track_ids: string[];
}

export interface PlaylistRecommendation {
  playlist: Playlist;
  score: number;
  reason?: string;
}

export interface GetRecommendationsParams {
  limit?: number;
  min_score?: number;
  include_own?: boolean;
}

/**
 * Rechercher des playlists
 *
 * ⚠️ MVP: This feature is disabled. Backend endpoint is not implemented.
 * TODO: Enable when backend implements GET /api/v1/playlists/search
 *
 * @see FEATURES.PLAYLIST_SEARCH
 */
export async function searchPlaylists(
  params: SearchPlaylistsParams,
): Promise<PlaylistListResponse> {
  requireFeature('PLAYLIST_SEARCH');
  const response = await apiClient.get<PlaylistListResponse>(
    '/playlists/search',
    { params },
  );
  return response.data;
}

/**
 * Créer un lien de partage
 *
 * ⚠️ MVP: This feature is disabled. Backend endpoint is not implemented.
 * TODO: Enable when backend implements POST /api/v1/playlists/:id/share
 *
 * @see FEATURES.PLAYLIST_SHARE
 */
export async function createShareLink(id: string): Promise<PlaylistShareLink> {
  requireFeature('PLAYLIST_SHARE');
  const response = await apiClient.post<{ share_link: PlaylistShareLink }>(
    `/playlists/${id}/share`,
  );
  return response.data.share_link;
}

/**
 * Réorganiser les tracks d'une playlist
 */
export async function reorderPlaylistTracks(
  id: string,
  data: ReorderTracksRequest,
): Promise<void> {
  await apiClient.put(`/playlists/${id}/tracks/reorder`, data);
}

/**
 * Retirer un track d'une playlist
 */
export async function removeTrackFromPlaylist(
  playlistId: string,
  trackId: string,
): Promise<void> {
  await apiClient.delete(`/playlists/${playlistId}/tracks/${trackId}`);
}

/**
 * Obtenir des recommandations de playlists
 *
 * ⚠️ MVP: This feature is disabled. Backend endpoint is not implemented.
 * TODO: Enable when backend implements GET /api/v1/playlists/recommendations
 *
 * @see FEATURES.PLAYLIST_RECOMMENDATIONS
 */
export async function getPlaylistRecommendations(
  _params: GetRecommendationsParams,
): Promise<{ recommendations: PlaylistRecommendation[] }> {
  requireFeature('PLAYLIST_RECOMMENDATIONS');
  // TODO: Replace with actual API call when backend is ready
  // const response = await apiClient.get<{ recommendations: PlaylistRecommendation[] }>('/playlists/recommendations', { params });
  // return response.data;

  // Mock response for now to satisfy type checker and frontend dev
  return Promise.resolve({
    recommendations: [],
  });
}

/**
 * Récupérer les collaborateurs
 */
/**
 * Récupérer les collaborateurs d'une playlist
 *
 * Backend endpoint: GET /playlists/:id/collaborators
 */
export async function getCollaborators(
  playlistId: string,
): Promise<PlaylistCollaborator[]> {
  // apiClient unwraps { success, data } format automatically
  const response = await apiClient.get<{
    collaborators: PlaylistCollaborator[];
  }>(`/playlists/${playlistId}/collaborators`);
  return response.data.collaborators || [];
}

/**
 * Ajouter un track à une playlist
 */
export async function addTrackToPlaylist(
  playlistId: string,
  trackId: string,
): Promise<void> {
  await apiClient.post(`/playlists/${playlistId}/tracks`, {
    track_id: trackId,
  });
}

/**
 * FE-COMP-017: Follow/Unfollow playlist functions
 */

export interface FollowPlaylistResponse {
  message: string;
  is_following: boolean;
}

/**
 * Suivre une playlist
 */
export async function followPlaylist(
  playlistId: string,
): Promise<FollowPlaylistResponse> {
  const response = await apiClient.post(`/playlists/${playlistId}/follow`);
  return {
    message: response.data.message || 'Playlist followed',
    is_following: true,
  };
}

/**
 * Ne plus suivre une playlist
 */
export async function unfollowPlaylist(
  playlistId: string,
): Promise<FollowPlaylistResponse> {
  const response = await apiClient.delete(`/playlists/${playlistId}/follow`);
  return {
    message: response.data.message || 'Playlist unfollowed',
    is_following: false,
  };
}

/**
 * Vérifier si l'utilisateur suit une playlist
 * Note: This uses the playlist data which may include is_following and follower_count
 */
export async function getPlaylistFollowStatus(
  playlistId: string,
): Promise<{ is_following: boolean; follower_count: number }> {
  // For now, we'll use the playlist data which may include follow status
  // In the future, this could use a dedicated endpoint
  const playlist = await getPlaylist(playlistId);
  return {
    is_following: (playlist as any).is_following ?? false,
    follower_count: (playlist as any).follower_count ?? 0,
  };
}
