"""
llmpm list             — show all installed models
llmpm info <model>     — show detailed info about a single model
llmpm uninstall <model> — uninstall a model
"""

# pylint: disable=duplicate-code
from __future__ import annotations

import shutil
from pathlib import Path

import click
from rich.console import Console
from rich.panel import Panel
from rich.table import Table

from llmpm import display
from llmpm.core import registry
from llmpm.display import fmt_size

_info_console = Console()


# ── list ──────────────────────────────────────────────────────────────────────

@click.command("list")
def list_models() -> None:
    """List all installed models."""
    display.header("installed models")
    display.blank()
    models = registry.all_models()
    display.models_table(models)


# ── info ──────────────────────────────────────────────────────────────────────

@click.command("info")
@click.argument("repo_id")
def info(repo_id: str) -> None:
    """Show detailed information about an installed model."""
    display.header(f"info {repo_id}")
    display.blank()

    entry = registry.get_model(repo_id)
    if not entry:
        display.error(
            f"Model [bold]{repo_id}[/] is not installed.\n\n"
            f"  Run:  [bold cyan]llmpm install {repo_id}[/]"
        )
        raise SystemExit(1)

    table = Table.grid(padding=(0, 2))
    table.add_column(style="dim", justify="right")
    table.add_column()

    badge = display.model_type_badge(entry.get("model_type", "?"))
    backend = (
        "llama.cpp"
        if entry["model_type"] == "gguf"
        else "HuggingFace Transformers"
    )

    table.add_row("model", f"[bold]{entry['repo_id']}[/]")
    table.add_row("type", badge)
    table.add_row("backend", backend)
    table.add_row("path", f"[dim]{entry['path']}[/]")

    if entry.get("primary_file"):
        table.add_row("primary file", f"[dim]{entry['primary_file']}[/]")

    if entry.get("files"):
        files_str = (
            "\n".join(f"[dim]  {fname}[/]" for fname in entry["files"])
            or "—"
        )
        table.add_row("files", files_str)

    if entry.get("size_bytes"):
        table.add_row("size", fmt_size(entry["size_bytes"]))

    if entry.get("installed_at"):
        table.add_row(
            "installed",
            entry["installed_at"][:19].replace("T", " "),
        )

    if entry.get("tags"):
        tags_str = "  ".join(
            f"[dim]{tag}[/]" for tag in entry["tags"][:8]
        )
        table.add_row("tags", tags_str)

    _info_console.print(Panel(table, border_style="dim", padding=(0, 2)))
    _info_console.print()


# ── uninstall ─────────────────────────────────────────────────────────────────

@click.command("uninstall")
@click.argument("repo_id")
@click.option("--yes", "-y", is_flag=True, help="Skip confirmation prompt.")
def uninstall(repo_id: str, yes: bool) -> None:
    """Uninstall a model."""
    display.header(f"uninstall {repo_id}")
    display.blank()

    entry = registry.get_model(repo_id)
    if not entry:
        display.error(f"Model [bold]{repo_id}[/] is not installed.")
        raise SystemExit(1)

    size_str = fmt_size(entry.get("size_bytes") or 0)
    display.warn(
        f"This will delete [bold]{repo_id}[/] "
        f"({size_str}) from disk."
    )
    display.blank()

    if not yes:
        confirmed = click.confirm("  Continue?", default=False)
        if not confirmed:
            display.info("Cancelled.")
            raise SystemExit(0)

    model_path = Path(entry["path"])
    if model_path.exists():
        shutil.rmtree(model_path, ignore_errors=True)
        display.ok(f"Deleted {model_path}")

    registry.unregister(repo_id)
    display.ok(f"Removed [bold]{repo_id}[/] from registry")
    display.blank()
