import { apiClient } from '@/services/api/client';
import { logger } from '@/utils/logger';

const CHUNK_SIZE = 1024 * 1024 * 2; // 2MB chunks

export interface UploadMetadata {
  title: string;
  artist?: string;
  album?: string;
  genre?: string;
}

export const uploadService = {
  /**
   * Effectue un upload partitionné (chunked) d'un fichier audio
   */
  uploadTrack: async (
    file: File,
    metadata: UploadMetadata,
    onProgress?: (progress: number) => void,
  ) => {
    const totalChunks = Math.ceil(file.size / CHUNK_SIZE);

    // 1. Initier l'upload
    const initiateResponse = await apiClient.post<{ upload_id: string }>(
      '/tracks/initiate',
      {
        filename: file.name,
        total_chunks: totalChunks,
        file_size: file.size,
        title: metadata.title,
        artist: metadata.artist,
        album: metadata.album,
        genre: metadata.genre,
      },
    );

    const { upload_id } = initiateResponse.data;
    logger.info(`[UPLOAD] Upload initiated with ID: ${upload_id}`, {
      filename: file.name,
      totalChunks,
    });

    // 2. Envoyer les morceaux (chunks)
    for (let i = 0; i < totalChunks; i++) {
      const start = i * CHUNK_SIZE;
      const end = Math.min(start + CHUNK_SIZE, file.size);
      const chunk = file.slice(start, end);

      const formData = new FormData();
      formData.append('chunk', chunk);
      formData.append('index', i.toString());
      formData.append('upload_id', upload_id);

      try {
        await apiClient.post('/tracks/chunk', formData, {
          // Utiliser le timeout long pour les uploads
          timeout: 300000,
          // Pas besoin de logger chaque chunk en détail (trop verbeux)
          _enableLogging: false,
        } as any);

        const progress = ((i + 1) / totalChunks) * 100;
        if (onProgress) onProgress(progress);
      } catch (error) {
        logger.error(`[UPLOAD] Failed to upload chunk ${i} for ${upload_id}`, {
          error,
        });
        throw error;
      }
    }

    // 3. Compléter l'upload
    const completeResponse = await apiClient.post<{ track_id: string }>(
      '/tracks/complete',
      {
        upload_id,
      },
    );

    logger.info(
      `[UPLOAD] Upload completed. Track ID: ${completeResponse.data.track_id}`,
    );
    return completeResponse.data;
  },

  /**
   * Récupère le statut d'une track en cours de traitement
   */
  getTrackStatus: async (trackId: string) => {
    const response = await apiClient.get<{ status: string; progress: number }>(
      `/tracks/${trackId}/status`,
    );
    return response.data;
  },
};
