"""
YouTube utilities for channel info, playlist info, and yt-dlp command generation.
"""

import json
import subprocess
from pathlib import Path
from typing import Any, Dict, List, Optional, Union
from karaoke_downloader.config_manager import AppConfig


def _parse_yt_dlp_command(yt_dlp_path: str) -> List[str]:
    """
    Parse yt-dlp path/command into a list of command arguments.
    Handles both file paths and command strings like 'python3 -m yt_dlp'.
    """
    if yt_dlp_path.startswith(('python', 'python3')):
        # It's a Python module command
        return yt_dlp_path.split()
    else:
        # It's a file path
        return [yt_dlp_path]


def get_channel_info(
    channel_url: str, yt_dlp_path: str = "downloader/yt-dlp.exe"
) -> tuple[str, str]:
    """Get channel information using yt-dlp. Returns (channel_name, channel_id)."""
    try:
        # Extract channel name from URL for now (faster than calling yt-dlp)
        if "/@" in channel_url:
            # Keep the @ symbol for cache key consistency
            channel_name = "@" + channel_url.split("/@")[1].split("/")[0]
        elif "/channel/" in channel_url:
            channel_name = channel_url.split("/channel/")[1].split("/")[0]
        else:
            channel_name = "Unknown"

        # Extract channel ID from URL (keep @ symbol for @ channels)
        if "/channel/" in channel_url:
            channel_id = channel_url.split("/channel/")[1].split("/")[0]
        elif "/@" in channel_url:
            # Keep the @ symbol for cache key consistency
            channel_id = "@" + channel_url.split("/@")[1].split("/")[0]
        else:
            channel_id = channel_url

        return channel_name, channel_id
    except Exception as e:
        print(f"❌ Failed to get channel info: {e}")
        return "Unknown", channel_url


def get_playlist_info(
    playlist_url: str, yt_dlp_path: str = "downloader/yt-dlp.exe"
) -> List[Dict[str, Any]]:
    """Get playlist information using yt-dlp."""
    try:
        cmd = _parse_yt_dlp_command(yt_dlp_path) + ["--dump-json", "--flat-playlist", playlist_url]
        result = subprocess.run(cmd, capture_output=True, text=True, check=True)
        videos = []
        for line in result.stdout.strip().split("\n"):
            if line.strip():
                videos.append(json.loads(line))
        return videos
    except subprocess.CalledProcessError as e:
        print(f"❌ Failed to get playlist info: {e}")
        return []


def build_yt_dlp_command(
    yt_dlp_path: str,
    video_url: str,
    output_path: Path,
    config: Union[AppConfig, Dict[str, Any]],
    additional_args: Optional[List[str]] = None,
) -> List[str]:
    """
    Build a standardized yt-dlp command with consistent arguments.

    Args:
        yt_dlp_path: Path to yt-dlp executable
        video_url: YouTube video URL
        output_path: Output file path
        config: Configuration dictionary with download settings
        additional_args: Optional additional arguments to append

    Returns:
        List of command arguments for subprocess.run
    """
    cmd = _parse_yt_dlp_command(yt_dlp_path) + [
        "--no-check-certificates",
        "--ignore-errors",
        "--no-warnings",
        "-o",
        str(output_path),
        "-f",
        config.download_settings.format,
        video_url,
    ]

    # Add any additional arguments
    if additional_args:
        cmd.extend(additional_args)

    return cmd


def execute_yt_dlp_command(
    cmd: List[str], timeout: Optional[int] = None
) -> subprocess.CompletedProcess:
    """
    Execute a yt-dlp command with standardized error handling.

    Args:
        cmd: Command list to execute
        timeout: Optional timeout in seconds

    Returns:
        CompletedProcess object

    Raises:
        subprocess.CalledProcessError: If the command fails
        subprocess.TimeoutExpired: If the command times out
    """
    return subprocess.run(
        cmd, capture_output=True, text=True, check=True, timeout=timeout
    )


def show_available_formats(
    video_url: str, yt_dlp_path: str = "downloader/yt-dlp.exe", timeout: int = 30
) -> None:
    """
    Show available formats for a video (debugging utility).

    Args:
        video_url: YouTube video URL
        yt_dlp_path: Path to yt-dlp executable
        timeout: Timeout in seconds
    """
    print(f"🔍 Checking available formats for: {video_url}")
    format_cmd = _parse_yt_dlp_command(yt_dlp_path) + ["--list-formats", video_url]
    try:
        format_result = subprocess.run(
            format_cmd, capture_output=True, text=True, timeout=timeout
        )
        print(f"📋 Available formats:\n{format_result.stdout}")
    except Exception as e:
        print(f"⚠️ Could not check formats: {e}")
