"""YouTube audio download service."""

import os
import yt_dlp
from typing import Tuple, Callable, Optional


def get_video_info(url: str) -> dict:
    """
    Fetch video metadata without downloading.

    Returns dict with: video_id, title, thumbnail, duration, channel
    """
    ydl_opts = {
        'quiet': True,
        'no_warnings': True,
        'extract_flat': False,
    }

    with yt_dlp.YoutubeDL(ydl_opts) as ydl:
        info = ydl.extract_info(url, download=False)

        # Format duration
        duration_secs = info.get('duration', 0)
        mins, secs = divmod(duration_secs, 60)
        hours, mins = divmod(mins, 60)
        if hours:
            duration = f"{hours}:{mins:02d}:{secs:02d}"
        else:
            duration = f"{mins}:{secs:02d}"

        return {
            'video_id': info.get('id', ''),
            'title': info.get('title', 'Unknown'),
            'thumbnail': info.get('thumbnail', ''),
            'duration': duration,
            'channel': info.get('channel', info.get('uploader', 'Unknown')),
        }


def download_audio(
    url: str,
    output_dir: str,
    progress_callback: Optional[Callable[[int, str], None]] = None
) -> Tuple[str, str, dict]:
    """
    Download audio from YouTube video with progress reporting.

    Args:
        url: YouTube video URL
        output_dir: Directory to save the audio file
        progress_callback: Optional callback(progress_percent, stage_message)

    Returns:
        Tuple of (file_path, video_title, video_info)
    """
    video_info = {}

    def progress_hook(d):
        if d['status'] == 'downloading':
            if progress_callback and d.get('total_bytes'):
                percent = int(d.get('downloaded_bytes', 0) / d['total_bytes'] * 100)
                progress_callback(percent, f"Downloading: {percent}%")
        elif d['status'] == 'finished':
            if progress_callback:
                progress_callback(100, "Download complete, converting...")

    ydl_opts = {
        'format': 'bestaudio/best',
        'postprocessors': [{
            'key': 'FFmpegExtractAudio',
            'preferredcodec': 'mp3',
            'preferredquality': '192',
        }],
        'outtmpl': os.path.join(output_dir, '%(id)s.%(ext)s'),
        'quiet': True,
        'no_warnings': True,
        'progress_hooks': [progress_hook],
    }

    with yt_dlp.YoutubeDL(ydl_opts) as ydl:
        info = ydl.extract_info(url, download=True)
        video_id = info['id']
        title = info.get('title', 'Unknown')
        file_path = os.path.join(output_dir, f"{video_id}.mp3")

        # Capture video info
        duration_secs = info.get('duration', 0)
        mins, secs = divmod(duration_secs, 60)
        hours, mins = divmod(mins, 60)
        if hours:
            duration = f"{hours}:{mins:02d}:{secs:02d}"
        else:
            duration = f"{mins}:{secs:02d}"

        video_info = {
            'video_id': video_id,
            'title': title,
            'thumbnail': info.get('thumbnail', ''),
            'duration': duration,
            'channel': info.get('channel', info.get('uploader', 'Unknown')),
            'url': url,
        }

    return file_path, title, video_info
