"""
Tool discovery commands for Amina CLI.

Commands:
    amina tools                    - List all available tools
    amina tools --category folding - Filter by category
    amina tools esmfold            - Show tool help (redirects to --help)
"""

import shutil
import subprocess
import sys
import typer
from typing import Optional
from rich.console import Console
from rich.table import Table

from amina_cli.commands.tools import get_all_tools, get_tool

app = typer.Typer(no_args_is_help=False)
console = Console()


def get_tools_by_category(category: str) -> list[dict]:
    """Get all tools in a specific category."""
    return [t for t in get_all_tools() if t.get("category") == category]


def get_categories() -> list[str]:
    """Get all available categories."""
    categories = set(t.get("category", "other") for t in get_all_tools())
    return sorted(categories)


def search_tools(query: str) -> list[dict]:
    """Search tools by name or description."""
    query_lower = query.lower()
    return [
        t
        for t in get_all_tools()
        if query_lower in t["name"].lower()
        or query_lower in t.get("description", "").lower()
        or query_lower in t.get("display_name", "").lower()
    ]


def _invoke_tool_help(tool_name: str):
    """Invoke 'amina run {tool} --help' to show tool help."""
    # Find the amina command - check if it's installed
    amina_cmd = shutil.which("amina")
    if amina_cmd:
        subprocess.run([amina_cmd, "run", tool_name, "--help"])
    else:
        # Fallback: Import and call directly
        from amina_cli.commands.run_cmd import app as run_app

        # Create a new Typer context and invoke the help
        ctx = typer.Context(run_app)
        console.print(f"\n[bold]amina run {tool_name} --help[/bold]\n")
        # Use click's invoke mechanism
        try:
            run_app(args=[tool_name, "--help"], standalone_mode=False)
        except SystemExit:
            pass  # --help exits with 0, which is expected


@app.callback(invoke_without_command=True)
def tools_callback(
    ctx: typer.Context,
    category: Optional[str] = typer.Option(
        None,
        "--category",
        "-c",
        help="Filter by category (e.g., folding, utilities)",
    ),
    search: Optional[str] = typer.Option(
        None,
        "--search",
        "-s",
        help="Search tools by name or description",
    ),
    tool_name: Optional[str] = typer.Argument(
        None,
        help="Tool name to get details for (redirects to --help)",
    ),
):
    """
    List and discover available tools.

    Examples:
        amina tools                      # List all tools
        amina tools --category folding   # Filter by category
        amina tools esmfold              # Show esmfold help
        amina tools --search fold        # Search tools
    """
    if ctx.invoked_subcommand is not None:
        return

    # Handle subcommand names that got captured as tool_name argument
    # (Typer processes callback arguments before subcommands)
    subcommands = {"list", "categories"}
    if tool_name in subcommands:
        # Call the subcommand directly
        if tool_name == "categories":
            list_categories()
            return
        elif tool_name == "list":
            list_tools(category=category)
            return

    # If tool name provided, show tool details and suggest --help for full parameters
    if tool_name:
        tool = get_tool(tool_name)
        if not tool:
            console.print(f"[red]Tool '{tool_name}' not found.[/red]")

            # Suggest similar tools
            similar = search_tools(tool_name)
            if similar:
                console.print("\n[dim]Did you mean:[/dim]")
                for t in similar[:3]:
                    console.print(f"  {t['name']}")

            console.print("\nRun [bold]amina tools[/bold] to see available tools.")
            raise typer.Exit(1)

        # Show tool details
        _show_tool_details(tool_name)
        return

    # Get tools (filtered if requested)
    if search:
        tools = search_tools(search)
        title = f"Tools matching '{search}'"
    elif category:
        tools = get_tools_by_category(category)
        title = f"Tools in category '{category}'"
    else:
        tools = get_all_tools()
        title = "Available Tools"

    if not tools:
        if search:
            console.print(f"[yellow]No tools found matching '{search}'[/yellow]")
        elif category:
            console.print(f"[yellow]No tools found in category '{category}'[/yellow]")
            console.print(f"\nAvailable categories: {', '.join(get_categories())}")
        else:
            console.print("[yellow]No tools available[/yellow]")
        return

    # Display tools grouped by category
    _show_tools_by_category(tools, title)

    # Show categories hint if listing all
    if not category and not search:
        categories = get_categories()
        console.print(f"\n[dim]Categories: {', '.join(categories)}[/dim]")
        console.print("[dim]Use --category <name> to filter, or specify a tool name for help[/dim]")


def _show_tools_by_category(tools: list[dict], title: str):
    """Display tools grouped by category."""
    console.print(f"[bold]{title}[/bold]\n")

    # Group by category
    by_category = {}
    for tool in tools:
        cat = tool.get("category", "other")
        by_category.setdefault(cat, []).append(tool)

    for category in sorted(by_category.keys()):
        console.print(f"[bold cyan]{category.title()}[/bold cyan]")
        for tool in by_category[category]:
            name = tool["name"]
            desc = tool.get("description", "")
            status = tool.get("status", "available")
            if status == "pending":
                console.print(f"  [dim]{name:20}[/dim] [dim]{desc} (coming soon)[/dim]")
            else:
                console.print(f"  {name:20} {desc}")
        console.print()


@app.command("list")
def list_tools(
    category: Optional[str] = typer.Option(
        None,
        "--category",
        "-c",
        help="Filter by category",
    ),
):
    """List all available tools."""
    if category:
        tools = get_tools_by_category(category)
        title = f"Tools in '{category}'"
    else:
        tools = get_all_tools()
        title = "Available Tools"

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

    _show_tools_table(tools, title)


def _show_tools_table(tools: list[dict], title: str):
    """Display tools in a formatted table."""
    table = Table(title=title, show_header=True, header_style="bold cyan")
    table.add_column("Tool", style="cyan", no_wrap=True)
    table.add_column("Category", style="dim")
    table.add_column("Status", style="dim")
    table.add_column("Description")

    for tool in tools:
        status = tool.get("status", "available")
        status_display = "[green]available[/green]" if status == "available" else "[dim]pending[/dim]"
        table.add_row(
            tool["name"],
            tool.get("category", "other"),
            status_display,
            tool.get("description", ""),
        )

    console.print(table)


@app.command("categories")
def list_categories():
    """List all tool categories."""
    categories = get_categories()

    console.print("[bold]Tool Categories:[/bold]\n")
    for cat in categories:
        tools = get_tools_by_category(cat)
        available = sum(1 for t in tools if t.get("status") == "available")
        pending = len(tools) - available
        console.print(f"  [cyan]{cat:15}[/cyan] ({available} available, {pending} pending)")

    console.print("\nUse: amina tools --category <name>")


def _show_tool_details(tool_name: str):
    """Display detailed information about a tool."""
    tool = get_tool(tool_name)
    if not tool:
        console.print(f"[red]Tool '{tool_name}' not found.[/red]")
        return

    console.print(f"\n[bold]{tool.get('display_name', tool_name)}[/bold]")
    console.print(f"Category: {tool.get('category', 'other')}")

    description = tool.get("description", "")
    if description:
        console.print(f"Description: {description}")

    # Show outputs
    outputs = tool.get("outputs", {})
    if outputs:
        console.print("\n[bold]Outputs:[/bold]")
        for key, desc in outputs.items():
            console.print(f"  {key}: {desc}")

    # Show parameters if available (legacy support for tests)
    parameters = tool.get("parameters", {})
    if parameters:
        console.print("\n[bold]Parameters:[/bold]")
        for param_name, param_info in parameters.items():
            if isinstance(param_info, dict):
                param_desc = param_info.get("description", "")
                required = param_info.get("required", False)
                param_type = param_info.get("type", "")
                req_marker = " (required)" if required else ""
                console.print(f"  {param_name}: {param_type}{req_marker}")
                if param_desc:
                    console.print(f"    {param_desc}")
            else:
                console.print(f"  {param_name}: {param_info}")
    else:
        # Parameters come from CLI definition, suggest --help
        console.print("\n[bold]Parameters:[/bold]")
        console.print(f"  Run 'amina run {tool_name} --help' for full parameter list")
