"""
Audio transcription module using API-based services.
Supports chunking long audio files into 10-minute segments.
"""

import tempfile
import os
import requests

# Lazy imports for optional providers
try:
    from openai import OpenAI
    OPENAI_AVAILABLE = True
except ImportError:
    OPENAI_AVAILABLE = False

try:
    from groq import Groq
    GROQ_AVAILABLE = True
except ImportError:
    GROQ_AVAILABLE = False

try:
    from mistralai import Mistral
    MISTRAL_AVAILABLE = True
except ImportError:
    MISTRAL_AVAILABLE = False

# Handle imports for both running from src and from parent directory
try:
    from audio_processor import split_audio_into_chunks
except ImportError:
    from .audio_processor import split_audio_into_chunks


def get_audio_duration(audio_file_path):
    """
    Get audio file duration in seconds using PyAV.
    
    Args:
        audio_file_path (str): Path to audio file
        
    Returns:
        float: Duration in seconds
    """
    try:
        import av
        container = av.open(audio_file_path)
        duration = float(container.duration) / av.time_base if container.duration else 0
        container.close()
        return duration
    except Exception as e:
        print(f"Warning: Could not determine audio duration: {e}")
        return 0


def transcribe_audio_chunk(audio_file_path, provider, api_key):
    """
    Transcribe a single audio chunk.
    
    Args:
        audio_file_path (str): Path to audio file
        provider (str): Provider name (openai, groq, mistral)
        api_key (str): API key for the provider
        
    Returns:
        str: Transcribed text
    """
    if provider == "openai":
        if not OPENAI_AVAILABLE:
            raise ValueError("OpenAI provider not available. Install with: pip install ytqgen[openai]")
        
        client = OpenAI(api_key=api_key)
        with open(audio_file_path, "rb") as audio_file:
            transcription = client.audio.transcriptions.create(
                model="whisper-1",
                file=audio_file
            )
        return transcription.text
    
    elif provider == "groq":
        if not GROQ_AVAILABLE:
            raise ValueError("Groq provider not available. Install with: pip install ytqgen[groq]")
        
        client = Groq(api_key=api_key)
        with open(audio_file_path, "rb") as audio_file:
            transcription = client.audio.transcriptions.create(
                model="whisper-large-v3",
                file=audio_file
            )
        return transcription.text
    
    elif provider == "mistral":
        if not MISTRAL_AVAILABLE:
            raise ValueError("Mistral provider not available. Install with: pip install ytqgen[mistral]")
        
        # Use Mistral's Voxtral API with requests
        url = "https://api.mistral.ai/v1/audio/transcriptions"
        headers = {"Authorization": f"Bearer {api_key}"}
        
        with open(audio_file_path, "rb") as audio_file:
            files = {"file": audio_file}
            data = {"model": "voxtral-mini-latest"}
            response = requests.post(url, headers=headers, files=files, data=data)
        
        if response.status_code == 200:
            result = response.json()
            transcription_text = result.get("text", "").strip()
            if transcription_text:
                return transcription_text
            else:
                raise ValueError("Mistral API returned empty transcription.")
        else:
            raise ValueError(f"Mistral API error: {response.status_code} - {response.text}")
    
    else:
        raise ValueError(f"Unsupported provider: {provider}")


def transcribe_audio(audio_file_path, chunk_duration_minutes=10):
    """
    Transcribes audio data using API-based services (OpenAI Whisper, Groq, or Mistral Voxtral).
    For audio longer than 10 minutes, automatically chunks it and processes each chunk separately.
    
    Args:
        audio_file_path (str): Path to the audio file
        chunk_duration_minutes (int): Duration of each chunk in minutes (default: 10)
        
    Returns:
        str: Transcribed text
        
    Raises:
        ValueError: If provider is not supported or API key is missing
    """
    # Read environment variables at call time (not import time)
    provider = os.getenv("TRANSCRIPTION_PROVIDER", "openai").lower()
    
    # Get API key based on provider
    if provider == "openai":
        api_key = os.getenv("OPENAI_API_KEY", "")
        if not api_key:
            raise ValueError("OPENAI_API_KEY is not set. Please set it in environment variables.")
    elif provider == "groq":
        api_key = os.getenv("GROQ_API_KEY", "")
        if not api_key:
            raise ValueError("GROQ_API_KEY is not set. Please set it in environment variables.")
    elif provider == "mistral":
        api_key = os.getenv("MISTRAL_API_KEY", "")
        if not api_key:
            raise ValueError("MISTRAL_API_KEY is not set. Please set it in environment variables.")
    else:
        raise ValueError(f"Unsupported transcription provider: {provider}. Supported: openai, groq, mistral")
    
    try:
        # Check audio duration
        duration_seconds = get_audio_duration(audio_file_path)
        duration_minutes = duration_seconds / 60
        chunk_duration_seconds = chunk_duration_minutes * 60
        
        print(f"Audio duration: {duration_minutes:.1f} minutes")
        
        # If audio is shorter than chunk duration, transcribe directly
        if duration_seconds <= chunk_duration_seconds or duration_seconds == 0:
            print(f"Transcribing audio with {provider.title()}...")
            transcription_text = transcribe_audio_chunk(audio_file_path, provider, api_key)
            print(f"Transcription completed using {provider.title()}. ({len(transcription_text.split())} words)")
            return transcription_text
        
        # For longer audio, split into chunks
        print(f"Audio is longer than {chunk_duration_minutes} minutes, splitting into chunks...")
        chunk_paths = split_audio_into_chunks(audio_file_path, chunk_duration_seconds)
        
        all_transcriptions = []
        
        for i, chunk_path in enumerate(chunk_paths):
            print(f"Transcribing chunk {i + 1}/{len(chunk_paths)} with {provider.title()}...")
            try:
                chunk_transcription = transcribe_audio_chunk(chunk_path, provider, api_key)
                word_count = len(chunk_transcription.split())
                print(f"  Chunk {i + 1} transcription: {word_count} words")
                all_transcriptions.append(chunk_transcription)
            except Exception as e:
                print(f"  Warning: Error transcribing chunk {i + 1}: {e}")
                all_transcriptions.append("")  # Continue with other chunks
            finally:
                # Clean up chunk file
                try:
                    if os.path.exists(chunk_path):
                        os.remove(chunk_path)
                except Exception as e:
                    print(f"  Warning: Could not delete chunk file {chunk_path}: {e}")
        
        # Combine all transcriptions
        full_transcription = " ".join(all_transcriptions)
        total_words = len(full_transcription.split())
        print(f"All chunks transcribed. Total: {total_words} words")
        
        return full_transcription
        
    except Exception as e:
        print(f"Error during transcription: {e}")
        raise
