import shutil
import subprocess
import sys
from importlib.metadata import entry_points
from typing import Optional

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

NEXUS_INDEX_URL = "https://nexus3.khinternal.net/repository/pypi-all/simple"
DEFAULT_PACKAGE = "komodo-internal-tools"

plugin_app = typer.Typer(
    help="Manage Komodo CLI plugins.",
    no_args_is_help=True,
)


def _get_installer() -> list[str]:
    """Return the best available pip-install command prefix.

    Tries in order: ``uv pip`` > ``python -m pip`` > ``pip3`` > ``pip``.
    """
    uv = shutil.which("uv")
    if uv:
        return [uv, "pip"]

    probe = subprocess.run(
        [sys.executable, "-m", "pip", "--version"],
        capture_output=True,
    )
    if probe.returncode == 0:
        return [sys.executable, "-m", "pip"]

    for name in ("pip3", "pip"):
        path = shutil.which(name)
        if path:
            return [path]

    return [sys.executable, "-m", "pip"]


@plugin_app.command()
def install(
    package: str = typer.Argument(DEFAULT_PACKAGE, help="Package name to install."),
    path: Optional[str] = typer.Option(None, "--path", "-p", help="Install from a local directory path (editable mode)."),
) -> None:
    """Install a Komodo plugin package from Nexus or a local path."""
    console = Console()
    installer = _get_installer()

    if path:
        console.print(Text(f"Installing {package} from local path: {path}", style="bold cyan"))
        cmd = [*installer, "install", "-e", path]
    else:
        console.print(Text(f"Installing {package} from Nexus...", style="bold cyan"))
        cmd = [*installer, "install", "--index-url", NEXUS_INDEX_URL, package]

    result = subprocess.run(cmd, capture_output=True, text=True)

    if result.returncode == 0:
        console.print(Text(f"Successfully installed {package}.", style="bold green"))
        console.print(Text("Restart the CLI or MCP server to pick up new plugins.", style="dim"))
    else:
        console.print(Text(f"Failed to install {package}.", style="bold red"))
        if result.stdout:
            console.print(result.stdout)
        if result.stderr:
            console.print(result.stderr)
        raise typer.Exit(code=1)


@plugin_app.command()
def uninstall(
    package: str = typer.Argument(DEFAULT_PACKAGE, help="Package name to uninstall."),
) -> None:
    """Uninstall a Komodo plugin package."""
    console = Console()
    installer = _get_installer()

    console.print(Text(f"Uninstalling {package}...", style="bold cyan"))

    cmd = [*installer, "uninstall", package]
    if "uv" not in str(installer[0]).lower():
        cmd.insert(-1, "-y")

    result = subprocess.run(cmd, capture_output=True, text=True)

    if result.returncode == 0:
        console.print(Text(f"Successfully uninstalled {package}.", style="bold green"))
    else:
        console.print(Text(f"Failed to uninstall {package}.", style="bold red"))
        if result.stdout:
            console.print(result.stdout)
        if result.stderr:
            console.print(result.stderr)
        raise typer.Exit(code=1)


@plugin_app.command(name="list")
def list_plugins() -> None:
    """List installed Komodo plugins."""
    console = Console()

    cli_plugins = list(entry_points(group="komodo.cli_plugins"))
    mcp_plugins = list(entry_points(group="komodo.mcp_plugins"))

    if not cli_plugins and not mcp_plugins:
        console.print(Text("No plugins installed.", style="dim"))
        console.print(Text("Install the internal tools with: komodo plugin install", style="dim"))
        return

    table = Table(title="Installed Komodo Plugins", show_header=True, header_style="bold cyan")
    table.add_column("Name", style="green")
    table.add_column("Type", style="yellow")
    table.add_column("Entry Point", style="dim")

    for ep in cli_plugins:
        table.add_row(ep.name, "CLI", str(ep.value))
    for ep in mcp_plugins:
        table.add_row(ep.name, "MCP", str(ep.value))

    console.print(table)
