export interface AudioMetadata {
  duration: number
  title?: string
  artist?: string
  album?: string
  bitrate?: number
  sampleRate?: number
}

/**
 * Validate audio file before upload
 */
export function validateAudioFile(file: File): { valid: boolean; error?: string } {
  const maxSize = 500 * 1024 * 1024 // 500MB
  const allowedTypes = [
    "audio/mpeg",
    "audio/mp3",
    "audio/flac",
    "audio/wav",
    "audio/aac",
    "audio/ogg",
    "audio/mp4",
    "audio/x-m4a",
  ]
  const allowedExtensions = [".mp3", ".flac", ".wav", ".aac", ".ogg", ".m4a"]

  const hasValidType = allowedTypes.includes(file.type)
  const hasValidExtension = allowedExtensions.some((ext) => file.name.toLowerCase().endsWith(ext))

  if (!hasValidType && !hasValidExtension) {
    return {
      valid: false,
      error: "Format audio non supporté. Utilisez MP3, FLAC, WAV, AAC, OGG ou M4A.",
    }
  }

  if (file.size > maxSize) {
    return {
      valid: false,
      error: "Fichier trop volumineux. Maximum 500MB.",
    }
  }

  const minSize = 100 * 1024 // 100KB minimum
  if (file.size < minSize) {
    return {
      valid: false,
      error: "Fichier audio trop petit. Minimum 100KB.",
    }
  }

  return { valid: true }
}

/**
 * Extract audio metadata from file
 */
export async function extractAudioMetadata(file: File): Promise<AudioMetadata> {
  return new Promise((resolve, reject) => {
    const audio = new Audio()
    const url = URL.createObjectURL(file)

    audio.addEventListener("loadedmetadata", () => {
      const metadata: AudioMetadata = {
        duration: Math.round(audio.duration),
      }

      URL.revokeObjectURL(url)
      resolve(metadata)
    })

    audio.addEventListener("error", () => {
      URL.revokeObjectURL(url)
      reject(new Error("Impossible de lire le fichier audio"))
    })

    audio.src = url
  })
}

/**
 * Format duration in seconds to MM:SS
 */
export function formatDuration(seconds: number): string {
  const mins = Math.floor(seconds / 60)
  const secs = seconds % 60
  return `${mins}:${secs.toString().padStart(2, "0")}`
}

/**
 * Format duration in milliseconds to MM:SS
 */
export function formatDurationMs(milliseconds: number): string {
  return formatDuration(Math.floor(milliseconds / 1000))
}

const CHUNK_SIZE = 2 * 1024 * 1024 // 2MB per chunk (safely under v0's ~3MB limit)

/**
 * Upload a single chunk
 */
async function uploadChunk(
  sessionId: string,
  chunk: Blob,
  chunkIndex: number,
  totalChunks: number,
  filename: string,
  contentType: string,
): Promise<{ complete: boolean; url?: string; received?: number; total?: number }> {
  const formData = new FormData()
  formData.append("sessionId", sessionId)
  formData.append("chunkIndex", chunkIndex.toString())
  formData.append("totalChunks", totalChunks.toString())
  formData.append("filename", filename)
  formData.append("contentType", contentType)
  formData.append("chunk", chunk)

  const response = await fetch("/api/upload/audio/chunk", {
    method: "POST",
    body: formData,
  })

  if (!response.ok) {
    const contentTypeHeader = response.headers.get("content-type")
    if (contentTypeHeader?.includes("application/json")) {
      const error = await response.json()
      throw new Error(error.error || `Upload failed: ${response.status}`)
    } else {
      const text = await response.text()
      throw new Error(`Upload failed: ${response.status} - ${text.substring(0, 100)}`)
    }
  }

  return response.json()
}

/**
 * Upload audio file using chunked upload approach
 * This splits the file into smaller pieces to bypass the serverless function body limit
 */
export async function uploadAudioFile(
  file: File,
  onProgress?: (progress: number) => void,
): Promise<{ url: string; duration: number }> {
  // First extract metadata
  const metadata = await extractAudioMetadata(file)

  const fileSizeMB = file.size / (1024 * 1024)
  console.log(`[v0] Starting chunked upload, file size: ${fileSizeMB.toFixed(2)} MB`)

  // Generate unique session ID
  const sessionId = `${Date.now()}-${Math.random().toString(36).substring(2, 15)}`

  // Calculate chunks
  const totalChunks = Math.ceil(file.size / CHUNK_SIZE)
  console.log(`[v0] Splitting into ${totalChunks} chunks of ${CHUNK_SIZE / (1024 * 1024)}MB each`)

  try {
    let uploadedUrl = ""

    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)

      console.log(`[v0] Uploading chunk ${i + 1}/${totalChunks}`)

      const result = await uploadChunk(sessionId, chunk, i, totalChunks, file.name, file.type || "audio/mpeg")

      // Update progress
      if (onProgress) {
        const progress = Math.round(((i + 1) / totalChunks) * 100)
        onProgress(progress)
      }

      if (result.complete && result.url) {
        uploadedUrl = result.url
        console.log(`[v0] Chunked upload complete: ${uploadedUrl}`)
      }
    }

    if (!uploadedUrl) {
      throw new Error("Upload incomplete - no URL received")
    }

    return { url: uploadedUrl, duration: metadata.duration }
  } catch (error) {
    console.error("[v0] Chunked upload error:", error)
    throw error instanceof Error ? error : new Error("Erreur lors du téléchargement")
  }
}

/**
 * Get audio quality label
 */
export function getAudioQualityLabel(bitrate: number): string {
  if (bitrate >= 320) return "Très élevé (320 kbps)"
  if (bitrate >= 256) return "Élevé (256 kbps)"
  if (bitrate >= 160) return "Normal (160 kbps)"
  if (bitrate >= 96) return "Économique (96 kbps)"
  return "Faible"
}
