"""CLI entry point for the Bamboo Claw client agent."""

import asyncio
import platform
import sys
from pathlib import Path

import click

from bamboo_claw_client.config import (
    ClientConfig,
    DEFAULT_CONFIG_PATH,
    DEFAULT_GATEWAY_URL,
    resolve_config_path,
)


@click.group()
@click.version_option(package_name="bamboo-claw")
def main():
    """Bamboo Claw client agent for OpenClaw gateways."""


@main.command()
@click.option("--config", "config_path", default=None, type=click.Path(path_type=Path), help="Path to config file")
@click.option("--server", default=None, help="Central server URL (e.g. ws://localhost:8000 or wss://central.example.com)")
@click.option("--gateway-url", default=None, help="Local OpenClaw gateway URL")
@click.option("--gateway-token", default=None, help="OpenClaw gateway token")
@click.option("--hostname", default=None, help="Hostname for this client (defaults to system hostname)")
def setup(
    config_path: Path | None,
    server: str | None,
    gateway_url: str | None,
    gateway_token: str | None,
    hostname: str | None,
):
    """Configure and register the client agent with the central server."""
    existing = ClientConfig.load(config_path)

    if not server:
        if existing.server_url:
            server = click.prompt("Server URL", default=existing.server_url, show_default=True)
        else:
            server = click.prompt("Server URL")

    if gateway_url is None:
        gateway_url = click.prompt(
            "Gateway URL",
            default=existing.gateway_url or DEFAULT_GATEWAY_URL,
            show_default=True,
        )

    if gateway_token is None:
        gateway_token = click.prompt(
            "Gateway Token (optional)",
            default=existing.gateway_token or "",
            show_default=bool(existing.gateway_token),
        )

    if hostname is None:
        hostname = click.prompt(
            "Hostname",
            default=existing.hostname or platform.node(),
            show_default=True,
        )

    config = ClientConfig(
        server_url=server,
        gateway_url=gateway_url,
        gateway_token=gateway_token,
        hostname=hostname,
        client_id=existing.client_id,
        token=existing.token,
    )
    config.ensure_client_id()
    config.save(config_path)
    click.echo(f"Config saved to {config_path or DEFAULT_CONFIG_PATH}")
    click.echo(f"  Client ID: {config.client_id}")

    if not config.token:
        click.echo("\nNo token found. Starting registration flow...")
        from bamboo_claw_client.registration import run_registration
        asyncio.run(run_registration(config))


@main.command()
@click.option("--config", "config_path", default=None, type=click.Path(), help="Path to config file")
def run(config_path: str | None):
    """Start the client agent."""
    path = Path(config_path) if config_path else None
    effective_path = resolve_config_path(path)
    config = ClientConfig.load(path)

    if not config.server_url:
        click.echo("Error: server URL not configured. Run 'bambooclaw setup' first.", err=True)
        sys.exit(1)

    if not config.token:
        click.echo("Error: no token. Run 'bambooclaw setup' to register.", err=True)
        sys.exit(1)

    if not config.client_id:
        config.ensure_client_id()
        config.save(path)

    click.echo(f"Starting Bamboo Claw client agent...")
    click.echo(f"  Config: {effective_path}")
    click.echo(f"  Server: {config.server_url}")
    click.echo(f"  Gateway: {config.gateway_url}")
    click.echo(f"  Hostname: {config.hostname}")

    from bamboo_claw_client.agent import run_agent
    asyncio.run(run_agent(config))


@main.command()
@click.option("--config", "config_path", default=None, type=click.Path(), help="Path to config file")
def status(config_path: str | None):
    """Show current client agent status."""
    path = Path(config_path) if config_path else None
    effective_path = resolve_config_path(path)
    config = ClientConfig.load(path)

    click.echo("Bamboo Claw Client Status")
    click.echo(f"  Config: {effective_path}")
    click.echo(f"  Server: {config.server_url or '(not configured)'}")
    click.echo(f"  Token: {'configured' if config.token else 'not set'}")
    click.echo(f"  Client ID: {config.client_id or '(not assigned)'}")
    click.echo(f"  Gateway: {config.gateway_url}")
    click.echo(f"  Hostname: {config.hostname or '(not set)'}")


@main.group(invoke_without_command=True)
@click.pass_context
def daemon(ctx: click.Context):
    """Manage Linux systemd daemon lifecycle."""
    if ctx.invoked_subcommand is None:
        _daemon_install(config_path=None)


@daemon.command("install")
@click.option("--config", "config_path", default=None, type=click.Path(path_type=Path), help="Optional config file path for service runtime")
def daemon_install(config_path: Path | None):
    """Install or update the systemd service."""
    _daemon_install(config_path=config_path)


@daemon.command("status")
def daemon_status():
    """Show concise status for the bamboo-claw service."""
    from bamboo_claw_client.daemon import DaemonError, status_service

    try:
        output = status_service()
    except DaemonError as exc:
        click.echo(f"Error: {exc}", err=True)
        sys.exit(1)
    click.echo(output)


@daemon.command("uninstall")
def daemon_uninstall():
    """Stop, disable, and remove the systemd service."""
    from bamboo_claw_client.daemon import DaemonError, uninstall_service

    try:
        uninstall_service()
    except DaemonError as exc:
        click.echo(f"Error: {exc}", err=True)
        sys.exit(1)
    click.echo("Uninstalled service bamboo-claw.service")


def _daemon_install(config_path: Path | None):
    from bamboo_claw_client.daemon import DaemonError, install_service

    try:
        unit_path = install_service(config_path=config_path)
    except DaemonError as exc:
        click.echo(f"Error: {exc}", err=True)
        sys.exit(1)
    click.echo(f"Installed and started service: bamboo-claw.service ({unit_path})")


@main.command("windows-bat")
@click.option("--output", "output_path", required=True, type=click.Path(path_type=Path, dir_okay=False), help="Output path for generated .bat file")
@click.option("--working-dir", default=None, help="Working directory to cd into before startup")
@click.option("--venv-activate", default=None, help="Optional virtualenv activation script path")
@click.option("--config", "config_path", default=None, type=click.Path(), help="Optional config path for bambooclaw run")
def windows_bat(
    output_path: Path,
    working_dir: str | None,
    venv_activate: str | None,
    config_path: str | None,
):
    """Generate a Windows startup .bat script for NSSM service usage."""
    from bamboo_claw_client.daemon import write_windows_bat

    if output_path.suffix.lower() != ".bat":
        click.echo("Error: output path must end with .bat", err=True)
        sys.exit(1)

    written = write_windows_bat(
        output_path=output_path,
        working_dir=working_dir,
        venv_activate_path=venv_activate,
        config_path=config_path,
    )
    click.echo(f"Wrote Windows startup script: {written}")


if __name__ == "__main__":
    main()
