"""Unified CLI for Proxym — AI proxy management.

Usage:
  proxym serve                     # start the proxy server
  proxym status                    # show system status
  proxym accounts list             # manage accounts
  proxym accounts add --name Work --provider anthropic --api-key sk-ant-...
  proxym accounts costs            # cost breakdown
  proxym vm create --tool windsurf --account work-anthropic
  proxym vm start windsurf-work
  proxym vm open windsurf-work     # SPICE viewer
  proxym vm ssh windsurf-work      # SSH into VM
  proxym vm switch windsurf-work --project other-project
  proxym browser list              # show host browser profiles
  proxym browser assign {profile} --account {id}
  proxym browser sync {vm_id}
  proxym models                    # list available models

Command handlers live in proxym.cli/ sub-modules:
  - system.py   — serve, status, models
  - accounts.py — accounts list/add/costs
  - vms.py      — vm list/create/action/switch/open/ssh/logs
  - browser.py  — browser list/assign/sync/snapshot
"""

from __future__ import annotations

from types import SimpleNamespace

import click

from proxym.config import get_settings
from proxym.cli.system import cmd_serve, cmd_status, cmd_models
from proxym.cli.chat import cmd_chat
from proxym.cli.accounts import cmd_accounts_list, cmd_accounts_add, cmd_accounts_costs
from proxym.cli.vms import (
    cmd_vm_list, cmd_vm_create, cmd_vm_action, cmd_vm_switch,
    cmd_vm_open, cmd_vm_ssh, cmd_vm_logs,
)
from proxym.cli.browser import (
    cmd_browser_list, cmd_browser_assign, cmd_browser_sync, cmd_browser_snapshot,
)


def _make_args(ctx: click.Context, **kwargs) -> SimpleNamespace:
    """Create Namespace from ctx.obj with optional overrides."""
    d = dict(ctx.obj) if ctx.obj else {}
    d.update(kwargs)
    return SimpleNamespace(**d)


@click.group(invoke_without_command=True)
@click.option("--proxy", default=None, help="Proxy URL")
@click.option("--key", default=None, help="API key")
@click.option("--format", "fmt", default="table", type=click.Choice(["table", "yaml"]), help="Output format")
@click.pass_context
def cli(ctx: click.Context, proxy: str | None, key: str | None, fmt: str):
    """Proxym — intelligent AI proxy with VM isolation."""
    if ctx.invoked_subcommand is None:
        click.echo(ctx.get_help())
        ctx.exit(0)
    settings = get_settings()
    ctx.ensure_object(dict)
    ctx.obj["proxy"] = proxy or settings.default_proxy_url
    ctx.obj["key"] = key or settings.default_api_key
    ctx.obj["format"] = fmt


@cli.command(name="serve")
@click.option("--host", default=None, help="Bind host")
@click.option("--port", type=int, default=None, help="Bind port")
@click.option("--reload", is_flag=True, help="Auto-reload on changes")
def serve(host: str | None, port: int | None, reload: bool):
    """Start the proxy server."""
    args = SimpleNamespace(host=host, port=port, reload=reload)
    cmd_serve(args)


@cli.command(name="status")
@click.option("--format", "fmt", default="table", type=click.Choice(["table", "yaml"]))
@click.pass_context
def status(ctx: click.Context, fmt: str):
    """Show system status."""
    args = _make_args(ctx, format=fmt)
    cmd_status(args)


@cli.command(name="models")
@click.option("--format", "fmt", default="table", type=click.Choice(["table", "yaml"]))
@click.pass_context
def models(ctx: click.Context, fmt: str):
    """List available models."""
    args = _make_args(ctx, format=fmt)
    cmd_models(args)


@cli.command(name="chat")
@click.option("--voice", is_flag=True, help="Use microphone input (Whisper STT)")
@click.option("--tts", is_flag=True, help="Enable text-to-speech responses")
@click.pass_context
def chat(ctx: click.Context, voice: bool, tts: bool):
    """Interactive chat — DSL first, LLM fallback."""
    args = _make_args(ctx, voice=voice, tts=tts)
    cmd_chat(args)


@cli.group(name="accounts")
def accounts():
    """Manage accounts."""
    pass


@accounts.command(name="list")
@click.pass_context
def accounts_list(ctx: click.Context):
    """List accounts."""
    args = _make_args(ctx)
    cmd_accounts_list(args)


@accounts.command(name="add")
@click.option("--name", required=True, help="Account name")
@click.option("--provider", required=True, help="Provider name")
@click.option("--api-key", default="", help="API key")
@click.option("--email", default="", help="Email")
@click.option("--daily-budget", type=float, default=5.0, help="Daily budget")
@click.option("--monthly-budget", type=float, default=60.0, help="Monthly budget")
@click.option("--tags", default="", help="Tags")
@click.pass_context
def accounts_add(ctx: click.Context, name: str, provider: str, api_key: str,
                 email: str, daily_budget: float, monthly_budget: float, tags: str):
    """Add account."""
    args = _make_args(ctx, name=name, provider=provider, api_key=api_key,
                     email=email, daily_budget=daily_budget, monthly_budget=monthly_budget, tags=tags)
    cmd_accounts_add(args)


@accounts.command(name="costs")
@click.pass_context
def accounts_costs(ctx: click.Context):
    """Show cost breakdown."""
    args = _make_args(ctx)
    cmd_accounts_costs(args)


@cli.group(name="vm")
def vm():
    """Manage VMs."""
    pass


@vm.command(name="list")
@click.pass_context
def vm_list(ctx: click.Context):
    """List VMs."""
    args = _make_args(ctx)
    cmd_vm_list(args)


@vm.command(name="create")
@click.option("--name", default="", help="VM name")
@click.option("--tool", default="", help="Tool name")
@click.option("--account", default="", help="Account ID")
@click.option("--mount", default="", help="Mount path")
@click.option("--project", default="", help="Project path")
@click.option("--cpus", type=int, default=4, help="CPU count")
@click.option("--memory", type=int, default=6144, help="Memory in MB")
@click.option("--image", default="ubuntu-24.04", help="OS image")
@click.pass_context
def vm_create(ctx: click.Context, name: str, tool: str, account: str,
              mount: str, project: str, cpus: int, memory: int, image: str):
    """Create VM."""
    args = _make_args(ctx, name=name, tool=tool, account=account, mount=mount,
                     project=project, cpus=cpus, memory=memory, image=image)
    cmd_vm_create(args)


@vm.command(name="start")
@click.argument("vm_id")
@click.pass_context
def vm_start(ctx: click.Context, vm_id: str):
    """Start a VM."""
    args = _make_args(ctx, vm_id=vm_id, action="start")
    cmd_vm_action(args)


@vm.command(name="stop")
@click.argument("vm_id")
@click.option("--force", is_flag=True, help="Force stop")
@click.pass_context
def vm_stop(ctx: click.Context, vm_id: str, force: bool):
    """Stop a VM."""
    args = _make_args(ctx, vm_id=vm_id, action="stop", force=force)
    cmd_vm_action(args)


@vm.command(name="pause")
@click.argument("vm_id")
@click.pass_context
def vm_pause(ctx: click.Context, vm_id: str):
    """Pause a VM."""
    args = _make_args(ctx, vm_id=vm_id, action="pause")
    cmd_vm_action(args)


@vm.command(name="resume")
@click.argument("vm_id")
@click.pass_context
def vm_resume(ctx: click.Context, vm_id: str):
    """Resume a VM."""
    args = _make_args(ctx, vm_id=vm_id, action="resume")
    cmd_vm_action(args)


@vm.command(name="snapshot")
@click.argument("vm_id")
@click.option("--name", default=None, help="Snapshot name")
@click.pass_context
def vm_snapshot(ctx: click.Context, vm_id: str, name: str | None):
    """Snapshot a VM."""
    args = _make_args(ctx, vm_id=vm_id, action="snapshot", name=name)
    cmd_vm_action(args)


@vm.command(name="switch")
@click.argument("vm_id")
@click.option("--project", required=True, help="Project path")
@click.pass_context
def vm_switch(ctx: click.Context, vm_id: str, project: str):
    """Switch project in VM."""
    args = _make_args(ctx, vm_id=vm_id, project=project)
    cmd_vm_switch(args)


@vm.command(name="open")
@click.argument("vm_id")
@click.pass_context
def vm_open(ctx: click.Context, vm_id: str):
    """Open SPICE viewer."""
    args = _make_args(ctx, vm_id=vm_id)
    cmd_vm_open(args)


@vm.command(name="ssh")
@click.argument("vm_id")
@click.option("--user", default="dev", help="SSH user")
@click.pass_context
def vm_ssh(ctx: click.Context, vm_id: str, user: str):
    """SSH into VM."""
    args = _make_args(ctx, vm_id=vm_id, user=user)
    cmd_vm_ssh(args)


@vm.command(name="logs")
@click.argument("vm_id")
@click.pass_context
def vm_logs(ctx: click.Context, vm_id: str):
    """Show VM logs."""
    args = _make_args(ctx, vm_id=vm_id)
    cmd_vm_logs(args)


@cli.group(name="browser")
def browser():
    """Manage browser profiles."""
    pass


@browser.command(name="list")
@click.pass_context
def browser_list(ctx: click.Context):
    """List host browser profiles."""
    args = _make_args(ctx)
    cmd_browser_list(args)


@browser.command(name="assign")
@click.argument("profile")
@click.option("--account", required=True, help="Account ID")
@click.pass_context
def browser_assign(ctx: click.Context, profile: str, account: str):
    """Assign profile to account."""
    args = _make_args(ctx, profile=profile, account=account)
    cmd_browser_assign(args)


@browser.command(name="sync")
@click.argument("vm_id")
@click.pass_context
def browser_sync(ctx: click.Context, vm_id: str):
    """Sync browser profile host ↔ VM."""
    args = _make_args(ctx, vm_id=vm_id)
    cmd_browser_sync(args)


@browser.command(name="snapshot")
@click.argument("vm_id")
@click.pass_context
def browser_snapshot(ctx: click.Context, vm_id: str):
    """Save browser state from VM."""
    args = _make_args(ctx, vm_id=vm_id)
    cmd_browser_snapshot(args)


# CLI entry point
main = cli
