"""Audio transcription service using OpenAI Whisper."""

import os
from openai import OpenAI
from pydub import AudioSegment
from typing import List, Callable, Optional


MAX_FILE_SIZE = 25 * 1024 * 1024  # 25 MB (Whisper limit)


def split_audio(file_path: str, max_size_bytes: int = MAX_FILE_SIZE) -> List[str]:
    """
    Split audio file into chunks if it exceeds max size.

    Args:
        file_path: Path to the audio file
        max_size_bytes: Maximum file size before splitting

    Returns:
        List of chunk file paths
    """
    file_size = os.path.getsize(file_path)

    if file_size <= max_size_bytes:
        return [file_path]

    audio = AudioSegment.from_mp3(file_path)
    duration_ms = len(audio)

    # Calculate chunk duration based on file size ratio
    num_chunks = (file_size // max_size_bytes) + 1
    chunk_duration_ms = duration_ms // num_chunks

    chunks = []
    base_path = file_path.rsplit('.', 1)[0]

    for i in range(num_chunks):
        start = i * chunk_duration_ms
        end = min((i + 1) * chunk_duration_ms, duration_ms)
        chunk = audio[start:end]
        chunk_path = f"{base_path}_chunk_{i}.mp3"
        chunk.export(chunk_path, format="mp3")
        chunks.append(chunk_path)

    return chunks


def transcribe_audio(
    file_path: str,
    api_key: str,
    progress_callback: Optional[Callable[[int, str], None]] = None
) -> str:
    """
    Transcribe audio file using OpenAI Whisper API.
    Handles chunking for large files with progress reporting.

    Args:
        file_path: Path to the audio file
        api_key: OpenAI API key
        progress_callback: Optional callback(progress_percent, message)

    Returns:
        Transcribed text
    """
    client = OpenAI(api_key=api_key)
    chunks = split_audio(file_path)
    total_chunks = len(chunks)

    if progress_callback:
        progress_callback(0, f"Transcribing ({total_chunks} chunk{'s' if total_chunks > 1 else ''})...")

    transcriptions = []
    for i, chunk_path in enumerate(chunks):
        if progress_callback:
            percent = int((i / total_chunks) * 100)
            progress_callback(percent, f"Transcribing chunk {i + 1}/{total_chunks}...")

        with open(chunk_path, 'rb') as audio_file:
            response = client.audio.transcriptions.create(
                model="whisper-1",
                file=audio_file,
                response_format="text"
            )
            transcriptions.append(response)

        # Clean up chunk files (but not the original)
        if chunk_path != file_path:
            os.remove(chunk_path)

        if progress_callback:
            percent = int(((i + 1) / total_chunks) * 100)
            progress_callback(percent, f"Completed chunk {i + 1}/{total_chunks}")

    return " ".join(transcriptions)


def cleanup_audio(file_path: str):
    """Remove audio file after transcription."""
    if os.path.exists(file_path):
        os.remove(file_path)


def text_to_srt(text: str, title: str = "") -> str:
    """Convert plain text to SRT subtitle format."""
    words = text.split()
    lines = []
    current_line = []
    word_count = 0

    # Split into ~10 word segments
    for word in words:
        current_line.append(word)
        word_count += 1
        if word_count >= 10:
            lines.append(' '.join(current_line))
            current_line = []
            word_count = 0

    if current_line:
        lines.append(' '.join(current_line))

    # Generate SRT with estimated timing (3 seconds per line)
    srt_content = []
    for i, line in enumerate(lines):
        start_secs = i * 3
        end_secs = (i + 1) * 3
        start_time = f"{start_secs // 3600:02d}:{(start_secs % 3600) // 60:02d}:{start_secs % 60:02d},000"
        end_time = f"{end_secs // 3600:02d}:{(end_secs % 3600) // 60:02d}:{end_secs % 60:02d},000"
        srt_content.append(f"{i + 1}\n{start_time} --> {end_time}\n{line}\n")

    return '\n'.join(srt_content)


def text_to_vtt(text: str, title: str = "") -> str:
    """Convert plain text to WebVTT subtitle format."""
    words = text.split()
    lines = []
    current_line = []
    word_count = 0

    for word in words:
        current_line.append(word)
        word_count += 1
        if word_count >= 10:
            lines.append(' '.join(current_line))
            current_line = []
            word_count = 0

    if current_line:
        lines.append(' '.join(current_line))

    vtt_content = ["WEBVTT", ""]
    for i, line in enumerate(lines):
        start_secs = i * 3
        end_secs = (i + 1) * 3
        start_time = f"{start_secs // 3600:02d}:{(start_secs % 3600) // 60:02d}:{start_secs % 60:02d}.000"
        end_time = f"{end_secs // 3600:02d}:{(end_secs % 3600) // 60:02d}:{end_secs % 60:02d}.000"
        vtt_content.append(f"{start_time} --> {end_time}\n{line}\n")

    return '\n'.join(vtt_content)
