"""CLI entry point for beacon-dl.

This module provides the command-line interface for the BeaconTV downloader.
"""

from pathlib import Path

import typer
from rich.console import Console
from rich.table import Table

from .auth import get_cookie_file
from .config import settings
from .content import get_video_content
from .downloader import BeaconDownloader
from .graphql import BeaconGraphQL
from .history import DownloadHistory

app = typer.Typer(
    help="Beacon TV Downloader - Simplified direct download",
    invoke_without_command=True,
    no_args_is_help=False,
)
console = Console()


@app.callback(invoke_without_command=True)
def default_callback(ctx: typer.Context) -> None:
    """Default to download command when no subcommand is provided."""
    if ctx.invoked_subcommand is None:
        # No subcommand provided - run download with defaults
        download(
            url=None,
            username=None,
            password=None,
            series=None,
            debug=False,
        )


def get_authenticated_cookie_file(
    username: str | None = None,
    password: str | None = None,
) -> Path:
    """Get authenticated cookie file, prompting for login if needed.

    Args:
        username: Optional username override
        password: Optional password override

    Returns:
        Path to cookie file

    Raises:
        typer.Exit: If authentication fails
    """
    # Update settings if provided
    if username:
        settings.beacon_username = username
    if password:
        settings.beacon_password = password

    cookie_file = get_cookie_file()

    if not cookie_file or not cookie_file.exists():
        console.print("[red]❌ No cookies found. Please login first.[/red]")
        console.print("[yellow]Use --username and --password to authenticate.[/yellow]")
        raise typer.Exit(code=1)

    return cookie_file


@app.command()
def download(
    url: str | None = typer.Argument(
        None, help="Beacon TV URL to download (default: latest episode from Campaign 4)"
    ),
    username: str | None = typer.Option(None, help="Beacon TV Username"),
    password: str | None = typer.Option(None, help="Beacon TV Password"),
    series: str | None = typer.Option(
        None, help="Series slug to fetch latest episode from (default: campaign-4)"
    ),
    debug: bool = typer.Option(
        False, "--debug", help="Enable debug mode with verbose output"
    ),
) -> None:
    """
    Download video from Beacon TV.

    If no URL is provided, automatically downloads the latest episode from Campaign 4
    (or the series specified with --series).

    Examples:
        beacon-dl                                     # Latest from Campaign 4
        beacon-dl --series exu-calamity              # Latest from EXU Calamity
        beacon-dl https://beacon.tv/content/c4-e007  # Specific episode
    """
    try:
        if debug:
            settings.debug = debug
            console.print("[yellow]Debug mode enabled[/yellow]")
            console.print(
                f"[dim]Settings: resolution={settings.preferred_resolution}[/dim]"
            )

        console.print("[bold blue]Beacon TV Downloader[/bold blue]")

        # Get authenticated cookie file
        cookie_file = get_authenticated_cookie_file(username, password)

        # If no URL provided, fetch latest episode
        if not url:
            series_slug = series or "campaign-4"
            console.print(
                f"[yellow]No URL provided. Fetching latest episode from {series_slug}...[/yellow]"
            )

            client = BeaconGraphQL(cookie_file)
            latest = client.get_latest_episode(series_slug)

            if not latest:
                console.print(
                    f"[red]❌ Failed to get latest episode from {series_slug}[/red]"
                )
                raise typer.Exit(code=1)

            url = f"https://beacon.tv/content/{latest['slug']}"
            console.print(f"[green]✓ Latest: {latest['title']}[/green]")

        console.print(f"URL: {url}")

        # Download
        downloader = BeaconDownloader(cookie_file)
        downloader.download_url(url)

    except KeyboardInterrupt:
        console.print("\n[yellow]Download interrupted by user[/yellow]")
        raise typer.Exit(code=130)
    except typer.Exit:
        raise
    except Exception as e:
        console.print(f"[red]❌ Error: {e}[/red]")
        if settings.debug:
            console.print_exception()
        raise typer.Exit(code=1)


@app.command("list-series")
def list_series(
    username: str | None = typer.Option(None, help="Beacon TV Username"),
    password: str | None = typer.Option(None, help="Beacon TV Password"),
) -> None:
    """
    List all available series on Beacon TV.
    """
    try:
        console.print("[bold blue]Available Series on Beacon TV[/bold blue]\n")

        cookie_file = get_authenticated_cookie_file(username, password)

        client = BeaconGraphQL(cookie_file)
        collections = client.list_collections(series_only=True)

        if not collections:
            console.print("[yellow]No series found[/yellow]")
            return

        table = Table(show_header=True, header_style="bold cyan")
        table.add_column("Series Name", style="green")
        table.add_column("Slug", style="dim")
        table.add_column("Episodes", justify="right", style="yellow")

        for collection in collections:
            table.add_row(
                collection["name"],
                collection["slug"],
                str(collection.get("itemCount", "?")),
            )

        console.print(table)
        console.print(f"\n[dim]Total: {len(collections)} series[/dim]")

    except typer.Exit:
        raise
    except Exception as e:
        console.print(f"[red]❌ Error: {e}[/red]")
        raise typer.Exit(code=1)


@app.command("list-episodes")
def list_episodes(
    series: str = typer.Argument(..., help="Series slug (e.g., campaign-4)"),
    username: str | None = typer.Option(None, help="Beacon TV Username"),
    password: str | None = typer.Option(None, help="Beacon TV Password"),
) -> None:
    """
    List all episodes in a series.

    Example: beacon-dl list-episodes campaign-4
    """
    try:
        cookie_file = get_authenticated_cookie_file(username, password)

        client = BeaconGraphQL(cookie_file)

        # Get series info
        info = client.get_collection_info(series)
        if info:
            console.print(f"[bold blue]{info['name']}[/bold blue]")
            console.print(f"[dim]Total episodes: {info.get('itemCount', '?')}[/dim]\n")

        episodes = client.get_series_episodes(series)

        if not episodes:
            console.print(f"[yellow]No episodes found for series: {series}[/yellow]")
            return

        table = Table(show_header=True, header_style="bold cyan")
        table.add_column("Episode", style="yellow", width=10)
        table.add_column("Title", style="green")
        table.add_column("Release Date", style="dim", width=12)
        table.add_column("Duration", style="cyan", width=10)

        for episode in episodes:
            season = episode.get("seasonNumber", "?")
            ep_num = episode.get("episodeNumber", "?")
            episode_str = (
                f"S{season:02d}E{ep_num:02d}"
                if isinstance(season, int) and isinstance(ep_num, int)
                else f"S{season}E{ep_num}"
            )

            release_date = episode.get("releaseDate", "")
            date_str = release_date[:10] if release_date else "?"

            duration_ms = episode.get("duration", 0)
            if duration_ms:
                duration_sec = duration_ms // 1000
                hours = duration_sec // 3600
                minutes = (duration_sec % 3600) // 60
                duration_str = f"{hours}h {minutes}m"
            else:
                duration_str = "?"

            table.add_row(episode_str, episode["title"], date_str, duration_str)

        console.print(table)
        console.print(f"\n[dim]Total: {len(episodes)} episodes[/dim]")
        console.print("[dim]URL format: https://beacon.tv/content/{slug}[/dim]")

    except typer.Exit:
        raise
    except Exception as e:
        console.print(f"[red]❌ Error: {e}[/red]")
        raise typer.Exit(code=1)


@app.command("check-new")
def check_new(
    series: str = typer.Option(
        "campaign-4", help="Series slug to check (default: campaign-4)"
    ),
    username: str | None = typer.Option(None, help="Beacon TV Username"),
    password: str | None = typer.Option(None, help="Beacon TV Password"),
) -> None:
    """
    Check for new episodes in a series.

    Example: beacon-dl check-new --series campaign-4
    """
    try:
        console.print(f"[blue]Checking for new episodes in {series}...[/blue]")

        cookie_file = get_authenticated_cookie_file(username, password)

        client = BeaconGraphQL(cookie_file)
        latest = client.get_latest_episode(series)

        if not latest:
            console.print(f"[yellow]No episodes found for series: {series}[/yellow]")
            return

        season = latest.get("seasonNumber", "?")
        ep_num = latest.get("episodeNumber", "?")
        episode_str = (
            f"S{season:02d}E{ep_num:02d}"
            if isinstance(season, int) and isinstance(ep_num, int)
            else f"S{season}E{ep_num}"
        )

        release_date = latest.get("releaseDate", "")
        date_str = release_date[:10] if release_date else "Unknown"

        console.print("\n[green]✓ Latest episode found:[/green]")
        console.print(
            f"  [yellow]{episode_str}[/yellow] - [bold]{latest['title']}[/bold]"
        )
        console.print(f"  Released: {date_str}")
        console.print(f"  URL: https://beacon.tv/content/{latest['slug']}")

        console.print("\n[dim]To download:[/dim]")
        console.print(f"  beacon-dl https://beacon.tv/content/{latest['slug']}")
        console.print("  [dim]or just:[/dim]")
        console.print("  beacon-dl  [dim](downloads latest automatically)[/dim]")

    except typer.Exit:
        raise
    except Exception as e:
        console.print(f"[red]❌ Error: {e}[/red]")
        raise typer.Exit(code=1)


@app.command("batch-download")
def batch_download(
    series: str = typer.Argument(..., help="Series slug (e.g., campaign-4)"),
    start: int = typer.Option(
        1, "--start", "-s", help="Start episode number (default: 1)"
    ),
    end: int | None = typer.Option(
        None, "--end", "-e", help="End episode number (default: all)"
    ),
    username: str | None = typer.Option(None, help="Beacon TV Username"),
    password: str | None = typer.Option(None, help="Beacon TV Password"),
    debug: bool = typer.Option(False, "--debug", help="Enable debug mode"),
) -> None:
    """
    Batch download multiple episodes from a series.

    Example:
        beacon-dl batch-download campaign-4              # Download all episodes
        beacon-dl batch-download campaign-4 --start 1 --end 5  # Download episodes 1-5
    """
    try:
        if debug:
            settings.debug = debug

        console.print(f"[bold blue]Batch Download: {series}[/bold blue]\n")

        cookie_file = get_authenticated_cookie_file(username, password)

        client = BeaconGraphQL(cookie_file)
        episodes = client.get_series_episodes(series)

        if not episodes:
            console.print(f"[yellow]No episodes found for series: {series}[/yellow]")
            return

        # Filter episodes by range
        filtered_episodes = []
        for episode in episodes:
            ep_num = episode.get("episodeNumber")
            if ep_num is None:
                continue
            if ep_num < start:
                continue
            if end is not None and ep_num > end:
                continue
            filtered_episodes.append(episode)

        if not filtered_episodes:
            console.print(
                f"[yellow]No episodes found in range {start}-{end or 'end'}[/yellow]"
            )
            return

        console.print(
            f"[green]Found {len(filtered_episodes)} episodes to download[/green]\n"
        )

        downloader = BeaconDownloader(cookie_file)
        success_count = 0
        failed_count = 0

        for i, episode in enumerate(filtered_episodes, 1):
            url = f"https://beacon.tv/content/{episode['slug']}"
            console.print(
                f"\n[bold cyan]Downloading {i}/{len(filtered_episodes)}:[/bold cyan] {episode['title']}"
            )

            try:
                downloader.download_url(url)
                success_count += 1
            except Exception as e:
                console.print(f"[red]❌ Failed to download: {e}[/red]")
                failed_count += 1

                if settings.debug:
                    console.print_exception()

                if i < len(filtered_episodes):
                    continue_download = typer.confirm(
                        "\nContinue with next episode?", default=True
                    )
                    if not continue_download:
                        break

        console.print("\n[bold]Download Summary:[/bold]")
        console.print(f"  [green]✓ Success: {success_count}[/green]")
        if failed_count > 0:
            console.print(f"  [red]✗ Failed: {failed_count}[/red]")

    except KeyboardInterrupt:
        console.print("\n[yellow]Batch download interrupted by user[/yellow]")
        raise typer.Exit(code=130)
    except typer.Exit:
        raise
    except Exception as e:
        console.print(f"[red]❌ Error: {e}[/red]")
        if settings.debug:
            console.print_exception()
        raise typer.Exit(code=1)


@app.command("history")
def show_history(
    limit: int = typer.Option(20, "--limit", "-n", help="Number of records to show"),
) -> None:
    """
    Show download history.

    Lists recent downloads with their status and metadata.
    """
    try:
        history = DownloadHistory()
        downloads = history.list_downloads(limit=limit)

        if not downloads:
            console.print("[yellow]No downloads in history yet[/yellow]")
            console.print(
                "[dim]Downloads will be tracked after your first download[/dim]"
            )
            return

        table = Table(show_header=True, header_style="bold cyan")
        table.add_column("Date", style="dim", width=12)
        table.add_column("Episode", style="yellow", width=10)
        table.add_column("Title", style="green")
        table.add_column("Size", justify="right", style="cyan", width=10)
        table.add_column("Status", width=8)

        for dl in downloads:
            # Parse date
            date_str = dl.downloaded_at[:10] if dl.downloaded_at else "?"

            # Parse episode from title
            episode_str = "?"
            import re

            match = re.match(r"C(\d+)\s+E(\d+)", dl.title)
            if match:
                episode_str = f"S{int(match.group(1)):02d}E{int(match.group(2)):02d}"
            else:
                match = re.match(r"S(\d+)E(\d+)", dl.title)
                if match:
                    episode_str = (
                        f"S{int(match.group(1)):02d}E{int(match.group(2)):02d}"
                    )

            # Format file size
            if dl.file_size:
                if dl.file_size >= 1_000_000_000:
                    size_str = f"{dl.file_size / 1_000_000_000:.1f} GB"
                elif dl.file_size >= 1_000_000:
                    size_str = f"{dl.file_size / 1_000_000:.1f} MB"
                else:
                    size_str = f"{dl.file_size / 1_000:.1f} KB"
            else:
                size_str = "?"

            # Status indicator
            status_str = (
                "[green]OK[/green]"
                if dl.status == "completed"
                else f"[red]{dl.status}[/red]"
            )

            # Title (truncate if too long)
            title = dl.title
            if len(title) > 40:
                title = title[:37] + "..."

            table.add_row(date_str, episode_str, title, size_str, status_str)

        console.print(table)
        console.print(f"\n[dim]Total: {history.count_downloads()} downloads[/dim]")

    except Exception as e:
        console.print(f"[red]Error: {e}[/red]")
        raise typer.Exit(code=1)


@app.command("verify")
def verify_files(
    filename: str | None = typer.Argument(
        None, help="Specific filename to verify (optional)"
    ),
    full: bool = typer.Option(
        False, "--full", "-f", help="Full verification with SHA256 hash check"
    ),
) -> None:
    """
    Verify integrity of downloaded files.

    Checks that downloaded files match their recorded size and optionally
    verifies SHA256 checksums. Without --full, only checks file size (fast).
    """
    try:
        history = DownloadHistory()
        downloads = history.list_downloads(limit=1000)

        if not downloads:
            console.print("[yellow]No downloads in history to verify[/yellow]")
            return

        if filename:
            # Verify specific file
            record = history.get_download_by_filename(filename)
            if not record:
                console.print(f"[red]File not found in history: {filename}[/red]")
                raise typer.Exit(code=1)
            downloads = [record]

        console.print(f"[blue]Verifying {len(downloads)} file(s)...[/blue]\n")

        valid_count = 0
        invalid_count = 0

        for dl in downloads:
            file_path = Path(dl.filename)

            if not file_path.exists():
                console.print(f"[red]MISSING[/red] {dl.filename}")
                invalid_count += 1
                continue

            # Check file size
            actual_size = file_path.stat().st_size
            if dl.file_size and actual_size != dl.file_size:
                console.print(f"[red]SIZE MISMATCH[/red] {dl.filename}")
                console.print(
                    f"  [dim]Expected: {dl.file_size}, Actual: {actual_size}[/dim]"
                )
                invalid_count += 1
                continue

            # Full verification with SHA256
            if full and dl.sha256:
                console.print(f"[dim]Checking SHA256 for {file_path.name}...[/dim]")
                actual_hash = DownloadHistory.calculate_sha256(file_path)
                if actual_hash != dl.sha256:
                    console.print(f"[red]HASH MISMATCH[/red] {dl.filename}")
                    console.print(f"  [dim]Expected: {dl.sha256[:16]}...[/dim]")
                    console.print(f"  [dim]Actual:   {actual_hash[:16]}...[/dim]")
                    invalid_count += 1
                    continue

            console.print(f"[green]OK[/green] {file_path.name}")
            valid_count += 1

        console.print("\n[bold]Verification Summary:[/bold]")
        console.print(f"  [green]Valid: {valid_count}[/green]")
        if invalid_count > 0:
            console.print(f"  [red]Invalid: {invalid_count}[/red]")

    except typer.Exit:
        raise
    except Exception as e:
        console.print(f"[red]Error: {e}[/red]")
        raise typer.Exit(code=1)


@app.command("clear-history")
def clear_history(
    force: bool = typer.Option(False, "--force", "-f", help="Skip confirmation prompt"),
) -> None:
    """
    Clear all download history.

    This removes all records from the history database but does not
    delete any downloaded files.
    """
    try:
        history = DownloadHistory()
        count = history.count_downloads()

        if count == 0:
            console.print("[yellow]History is already empty[/yellow]")
            return

        if not force:
            confirm = typer.confirm(
                f"Are you sure you want to clear {count} download record(s)?"
            )
            if not confirm:
                console.print("[yellow]Cancelled[/yellow]")
                return

        deleted = history.clear_history()
        console.print(f"[green]Cleared {deleted} download record(s)[/green]")

    except Exception as e:
        console.print(f"[red]Error: {e}[/red]")
        raise typer.Exit(code=1)


@app.command("rename")
def rename_files(
    directory: Path = typer.Argument(
        Path("."),
        help="Directory containing files to rename",
    ),
    dry_run: bool = typer.Option(
        True,
        "--dry-run/--execute",
        help="Show what would be renamed without making changes",
    ),
    pattern: str = typer.Option(
        "*.mkv",
        "--pattern",
        help="Glob pattern for files to consider",
    ),
) -> None:
    """
    Rename existing files to current naming schema.

    Finds files that match the old naming schema (with release group suffix)
    and renames them to the new schema (without release group).

    Use --execute to actually perform renames (default is --dry-run).

    Examples:
        beacon-dl rename                    # Dry-run in current directory
        beacon-dl rename ./downloads        # Dry-run in downloads folder
        beacon-dl rename --execute          # Actually rename files
        beacon-dl rename --pattern "*.mp4"  # Only rename mp4 files
    """
    import re

    try:
        console.print("[bold blue]File Renaming Tool[/bold blue]\n")

        if dry_run:
            console.print("[yellow]DRY RUN - no files will be renamed[/yellow]")
            console.print("[dim]Use --execute to actually rename files[/dim]\n")

        # Pattern to match release group suffix: "-GroupName.ext"
        # Matches alphanumeric release group names like Pawsty, RARBG, etc.
        release_group_pattern = re.compile(r"^(.+)-([A-Za-z0-9]+)\.(\w+)$")

        # Find files matching glob pattern
        files = list(directory.glob(pattern))
        if not files:
            console.print(f"[yellow]No files found matching '{pattern}' in {directory}[/yellow]")
            return

        history = DownloadHistory()
        renamed_count = 0
        skipped_count = 0

        for file_path in sorted(files):
            filename = file_path.name
            match = release_group_pattern.match(filename)

            if not match:
                # File doesn't have release group pattern
                continue

            base_name = match.group(1)
            release_group = match.group(2)
            extension = match.group(3)

            # New filename without release group
            new_filename = f"{base_name}.{extension}"
            new_path = file_path.parent / new_filename

            # Check if target already exists
            if new_path.exists():
                console.print(f"[yellow]SKIP[/yellow] {filename}")
                console.print(f"  [dim]Target already exists: {new_filename}[/dim]")
                skipped_count += 1
                continue

            if dry_run:
                console.print(f"[cyan]WOULD RENAME[/cyan] {filename}")
                console.print(f"  [dim]→ {new_filename}[/dim]")
                console.print(f"  [dim]  (removing release group: {release_group})[/dim]")
            else:
                # Actually rename the file
                file_path.rename(new_path)
                console.print(f"[green]RENAMED[/green] {filename}")
                console.print(f"  [dim]→ {new_filename}[/dim]")

                # Update history database if this file is tracked
                record = history.get_download_by_filename(filename)
                if record:
                    history.update_filename(record.content_id, new_filename)
                    console.print("  [dim]Updated history record[/dim]")

            renamed_count += 1

        console.print("\n[bold]Summary:[/bold]")
        if dry_run:
            console.print(f"  [cyan]Would rename: {renamed_count}[/cyan]")
        else:
            console.print(f"  [green]Renamed: {renamed_count}[/green]")
        if skipped_count > 0:
            console.print(f"  [yellow]Skipped: {skipped_count}[/yellow]")

        if dry_run and renamed_count > 0:
            console.print("\n[dim]Run with --execute to apply changes[/dim]")

    except Exception as e:
        console.print(f"[red]Error: {e}[/red]")
        if settings.debug:
            console.print_exception()
        raise typer.Exit(code=1)


def _extract_slug(url_or_slug: str) -> str:
    """Extract slug from URL or return as-is."""
    if url_or_slug.startswith("http"):
        # Extract from URL like https://beacon.tv/content/c4-e007
        return url_or_slug.split("/content/")[-1].split("?")[0]
    return url_or_slug


def _format_duration(seconds: int) -> str:
    """Convert seconds to 'Xh Ym' format."""
    hours = seconds // 3600
    minutes = (seconds % 3600) // 60
    if hours > 0:
        return f"{hours}h {minutes}m"
    return f"{minutes}m"


def _format_bitrate(kbps: int) -> str:
    """Format bitrate for display."""
    if kbps >= 1000:
        return f"{kbps / 1000:.1f} Mbps"
    return f"{kbps} kbps"


def _format_file_size(size_bytes: int) -> str:
    """Format file size for display."""
    if size_bytes >= 1_000_000_000:
        return f"{size_bytes / 1_000_000_000:.2f} GB"
    elif size_bytes >= 1_000_000:
        return f"{size_bytes / 1_000_000:.1f} MB"
    return f"{size_bytes / 1_000:.1f} KB"


@app.command("info")
def show_info(
    url_or_slug: str = typer.Argument(..., help="Episode URL or slug"),
    username: str | None = typer.Option(None, help="Beacon TV Username"),
    password: str | None = typer.Option(None, help="Beacon TV Password"),
) -> None:
    """
    Show detailed information about an episode.

    Displays available resolutions, subtitles, metadata, and download status.

    Examples:
        beacon-dl info c4-e007-on-the-scent
        beacon-dl info https://beacon.tv/content/c4-e007-on-the-scent
    """
    try:
        slug = _extract_slug(url_or_slug)
        console.print("[bold blue]Episode Information[/bold blue]\n")

        # Get authenticated cookie file
        cookie_file = get_authenticated_cookie_file(username, password)

        # Fetch video content
        content = get_video_content(slug, cookie_file)
        if not content:
            console.print(f"[red]Failed to fetch content for: {slug}[/red]")
            raise typer.Exit(code=1)

        meta = content.metadata

        # Episode info section
        console.print(f"[bold]Title:[/bold]       {meta.title}")
        if meta.collection_name:
            console.print(f"[bold]Series:[/bold]      {meta.collection_name}")
        if meta.season_number and meta.episode_number:
            console.print(
                f"[bold]Episode:[/bold]     S{meta.season_number:02d}E{meta.episode_number:02d}"
            )
        if meta.duration:
            # Duration from API is in milliseconds, convert to seconds
            duration_seconds = meta.duration // 1000
            console.print(
                f"[bold]Duration:[/bold]    {_format_duration(duration_seconds)}"
            )
        console.print(f"[bold]URL:[/bold]         https://beacon.tv/content/{slug}")

        # Description
        if meta.description:
            console.print("\n[bold]Description:[/bold]")
            # Truncate long descriptions
            desc = meta.description
            if len(desc) > 300:
                desc = desc[:297] + "..."
            console.print(f"  [dim]{desc}[/dim]")

        # Available resolutions table
        if content.sources:
            console.print("\n[bold cyan]Available Resolutions[/bold cyan]")
            res_table = Table(show_header=True, header_style="bold")
            res_table.add_column("Quality", style="yellow")
            res_table.add_column("Resolution", style="green")
            res_table.add_column("Bitrate", style="cyan", justify="right")
            res_table.add_column("Format", style="dim")

            for source in content.sources:
                res_table.add_row(
                    source.label or f"{source.height}p",
                    f"{source.width}x{source.height}",
                    _format_bitrate(source.bitrate) if source.bitrate else "?",
                    source.file_type or "video/mp4",
                )

            console.print(res_table)

        # Subtitles table
        if content.subtitles:
            console.print("\n[bold cyan]Subtitles[/bold cyan]")
            sub_table = Table(show_header=True, header_style="bold")
            sub_table.add_column("Language", style="green")
            sub_table.add_column("Code", style="dim")

            for sub in content.subtitles:
                sub_table.add_row(sub.label, sub.language)

            console.print(sub_table)
        else:
            console.print("\n[dim]No subtitles available[/dim]")

        # Download history status
        history = DownloadHistory()
        record = history.get_download_by_slug(slug)

        console.print()
        if record:
            console.print("[bold green]Download Status: ✓ Downloaded[/bold green]")
            console.print(f"  [dim]Filename:[/dim] {record.filename}")
            if record.file_size:
                console.print(
                    f"  [dim]Size:[/dim]     {_format_file_size(record.file_size)}"
                )
            if record.downloaded_at:
                date_str = record.downloaded_at[:10]
                console.print(f"  [dim]Date:[/dim]     {date_str}")
        else:
            console.print("[yellow]Download Status: Not downloaded[/yellow]")
            console.print(f"  [dim]Run: beacon-dl {slug}[/dim]")

    except typer.Exit:
        raise
    except Exception as e:
        console.print(f"[red]Error: {e}[/red]")
        if settings.debug:
            console.print_exception()
        raise typer.Exit(code=1)


def main() -> None:
    app()


if __name__ == "__main__":
    main()
