"""CLI for FlukeBase Connect client."""

import asyncio
import sys
from typing import Optional

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

from flukebase_connect import __version__
from flukebase_connect.config import get_config
from flukebase_connect.flukebase.client import FlukeBaseClient

app = typer.Typer(
    name="fbc",
    help="FlukeBase Connect - AI-assisted development CLI",
    no_args_is_help=True,
)
console = Console()


@app.command()
def version():
    """Show version information."""
    console.print(f"FlukeBase Connect v{__version__}")
    console.print(f"Python: {sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}")


@app.command()
def login(
    token: Optional[str] = typer.Option(None, "--token", "-t", help="API token"),
):
    """Authenticate with FlukeBase."""
    config = get_config()

    if not token:
        console.print("[yellow]Get your API token from:[/yellow] https://flukebase.me/user_settings/api_tokens")
        token = typer.prompt("Enter your API token", hide_input=True)

    if not token or not token.startswith("fbk_"):
        console.print("[red]Invalid token format. Token should start with 'fbk_'[/red]")
        raise typer.Exit(1)

    # Validate token
    config.flukebase.api_token = token
    client = FlukeBaseClient(config)

    try:
        result = asyncio.run(_validate_and_save(client, config, token))
        if result:
            console.print("[green]Successfully authenticated![/green]")
        else:
            console.print("[red]Authentication failed[/red]")
            raise typer.Exit(1)
    except Exception as e:
        console.print(f"[red]Error: {e}[/red]")
        raise typer.Exit(1)


async def _validate_and_save(client: FlukeBaseClient, config, token: str) -> bool:
    """Validate token and save config."""
    try:
        user = await client.get_current_user()
        console.print(f"Logged in as: [cyan]{user.email}[/cyan]")

        config.flukebase.api_token = token
        config.save()
        return True
    except Exception as e:
        console.print(f"[red]Validation failed: {e}[/red]")
        return False
    finally:
        await client.close()


@app.command()
def status():
    """Check FlukeBase connection status."""
    config = get_config()
    client = FlukeBaseClient(config)

    try:
        result = asyncio.run(_get_status(client))

        if result.get("connected"):
            console.print(Panel(
                f"[green]Connected[/green]\n"
                f"User: {result.get('user_email', 'Unknown')}\n"
                f"Projects: {result.get('project_count', 0)}",
                title="FlukeBase Status",
            ))
        else:
            console.print(Panel(
                "[red]Not connected[/red]\n\n"
                "Run [cyan]fbc login[/cyan] to authenticate.",
                title="FlukeBase Status",
            ))
    except Exception as e:
        console.print(f"[red]Error: {e}[/red]")
        raise typer.Exit(1)


async def _get_status(client: FlukeBaseClient) -> dict:
    """Get status asynchronously."""
    try:
        return await client.get_status()
    finally:
        await client.close()


@app.command()
def projects():
    """List your FlukeBase projects."""
    config = get_config()
    client = FlukeBaseClient(config)

    try:
        result = asyncio.run(_list_projects(client))

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

        table = Table(title="Your Projects")
        table.add_column("ID", style="cyan")
        table.add_column("Name", style="green")
        table.add_column("Framework")
        table.add_column("Stage")

        for project in result:
            table.add_row(
                str(project.id),
                project.name,
                project.framework or "-",
                project.stage or "-",
            )

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


async def _list_projects(client: FlukeBaseClient):
    """List projects asynchronously."""
    try:
        return await client.list_projects()
    finally:
        await client.close()


@app.command()
def doctor():
    """Check installation health."""
    console.print(Panel(
        f"[cyan]FlukeBase Connect v{__version__}[/cyan]\n"
        f"Python: {sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}",
        title="Installation Check",
    ))

    # Check configuration
    config = get_config()

    checks = []

    # Python version check
    if sys.version_info >= (3, 11):
        checks.append(("[green]\u2713[/green]", "Python version OK"))
    else:
        checks.append(("[red]\u2717[/red]", "Python 3.11+ required"))

    # Config directory
    if config.home.exists():
        checks.append(("[green]\u2713[/green]", f"Config directory: {config.home}"))
    else:
        checks.append(("[yellow]![/yellow]", "Config directory missing"))

    # Authentication
    if config.flukebase.api_token:
        checks.append(("[green]\u2713[/green]", "Authenticated"))
    else:
        checks.append(("[red]\u2717[/red]", "Not authenticated (run 'fbc login')"))

    # API URL
    checks.append(("[blue]i[/blue]", f"API URL: {config.flukebase.api_url}"))

    console.print("\n[bold]Checks:[/bold]")
    for icon, message in checks:
        console.print(f"  {icon} {message}")


@app.command()
def mcp():
    """Start MCP server (for AI assistant integration)."""
    from flukebase_connect.server import main as run_server
    run_server()


@app.command()
def tools():
    """List available MCP tools."""
    config = get_config()
    client = FlukeBaseClient(config)

    try:
        result = asyncio.run(_list_tools(client))

        if not result:
            console.print("[yellow]No tools available. Check your connection.[/yellow]")
            return

        table = Table(title="Available Tools")
        table.add_column("Name", style="cyan")
        table.add_column("Description")

        for tool in result:
            table.add_row(
                tool.get("name", ""),
                tool.get("description", "")[:60] + "..." if len(tool.get("description", "")) > 60 else tool.get("description", ""),
            )

        console.print(table)
        console.print(f"\n[dim]Total: {len(result)} tools[/dim]")
    except Exception as e:
        console.print(f"[red]Error: {e}[/red]")
        raise typer.Exit(1)


async def _list_tools(client: FlukeBaseClient):
    """List tools asynchronously."""
    try:
        return await client.list_available_tools()
    finally:
        await client.close()


def main():
    """Main entry point."""
    app()


if __name__ == "__main__":
    main()
