"""
Audio processing utilities for voice message transcription.
"""
import io
import logging
import mimetypes
import os
from typing import Optional

import httpx
from aiogram.types import Message

logger = logging.getLogger(__name__)


async def download_file_bytes(message: Message, file_id: str) -> bytes:
    """
    Download file bytes from Telegram.
    
    Args:
        message: Telegram message object
        file_id: File ID to download
        
    Returns:
        File bytes
        
    Raises:
        Exception: If download fails
    """
    buf = io.BytesIO()
    try:
        f = await message.bot.get_file(file_id)
        if getattr(f, "file_path", None):
            await message.bot.download_file(f.file_path, destination=buf)  # aiogram v2
        else:
            await message.bot.download(file_id, destination=buf)          # aiogram v3
    except Exception as e1:
        logger.warning("[audio] primary download path failed: %s, trying fallback", e1)
        try:
            await message.bot.download(file_id, destination=buf)
        except Exception as e2:
            logger.exception("[audio] download failed: %s", e2)
            raise
    return buf.getvalue()


async def transcribe_bytes_openai(audio_bytes: bytes, filename: str) -> str:
    """
    Transcribe audio bytes using OpenAI Whisper API.
    
    Args:
        audio_bytes: Audio file bytes
        filename: Original filename for MIME type detection
        
    Returns:
        Transcribed text
        
    Raises:
        RuntimeError: If API key is not set
        Exception: If transcription fails
    """
    api_key = os.getenv("OPENAI_API_KEY")
    if not api_key:
        logger.error("[audio] OPENAI_API_KEY is not set")
        raise RuntimeError("OPENAI_API_KEY is not set")

    mime = mimetypes.guess_type(filename)[0] or "audio/mpeg"
    files = {"file": (filename, audio_bytes, mime)}
    data = {"model": "whisper-1"}

    logger.info("[audio] transcribe start: filename=%s mime=%s size=%d", filename, mime, len(audio_bytes))
    
    async with httpx.AsyncClient(timeout=httpx.Timeout(120.0)) as client:
        for attempt in range(3):
            try:
                r = await client.post(
                    "https://api.openai.com/v1/audio/transcriptions",
                    headers={"Authorization": f"Bearer {api_key}"},
                    files=files,
                    data=data,
                )
                r.raise_for_status()
                j = r.json()
                text = (j.get("text") or "").strip()
                logger.info("[audio] transcribe done: len=%d preview=%r", len(text), text[:120])
                return text
            except httpx.HTTPStatusError as e:
                status = e.response.status_code
                if status in (429, 500, 502, 503, 504) and attempt < 2:
                    import asyncio
                    await asyncio.sleep(1.2 * (attempt + 1))
                    continue
                logger.exception("[audio] transcribe failed: status=%s body=%r", status, e.response.text[:200])
                raise


def get_audio_info(message: Message) -> tuple[str, str]:
    """
    Extract file ID and filename from audio message.
    
    Args:
        message: Telegram message with audio
        
    Returns:
        Tuple of (file_id, filename)
    """
    if message.voice:
        file_id = message.voice.file_id
        filename = f"voice_{message.voice.file_unique_id or 'tg'}.ogg"
        logger.info("[audio] voice recv: user_id=%s duration=%s",
                    message.from_user.id if message.from_user else "?", 
                    getattr(message.voice, "duration", None))
    elif message.audio:
        file_id = message.audio.file_id
        filename = message.audio.file_name or "audio.mp3"
        logger.info("[audio] audio recv: user_id=%s duration=%s name=%s",
                    message.from_user.id if message.from_user else "?", 
                    getattr(message.audio, "duration", None), filename)
    elif message.video_note:
        file_id = message.video_note.file_id
        filename = "video_note.mp4"
        logger.info("[audio] video_note recv: user_id=%s duration=%s",
                    message.from_user.id if message.from_user else "?", 
                    getattr(message.video_note, "duration", None))
    else:
        raise ValueError("Message does not contain audio content")
    
    return file_id, filename
