"""CLI commands: vm list/create/action/switch/open/ssh/logs — extracted from ctl.py."""

from __future__ import annotations

import os
import subprocess
import sys

from proxym.cli._client import make_client, print_table


def cmd_vm_list(args):
    c = make_client(args.proxy, args.key)
    data = c.get("/dashboard/vms").json()
    vms = data.get("vms", [])
    if not vms:
        print("No VMs configured. Use: proxym vm create ...")
        return
    rows = []
    for v in vms:
        rows.append({
            "id": v["id"],
            "name": v["name"],
            "state": v["state"],
            "tool": v.get("tool", ""),
            "ip": v.get("ip", ""),
            "mount": v.get("code_mount", ""),
        })
    print_table(rows, ["id", "name", "state", "tool", "ip", "mount"])


def cmd_vm_create(args):
    c = make_client(args.proxy, args.key)
    body = {
        "name": args.name,
        "tool": args.tool or "",
        "account_id": args.account or "",
        "vcpus": args.cpus,
        "memory_mb": args.memory,
        "code_mount_host": args.mount or "",
        "base_image": args.image,
        "project": args.project or "",
    }
    result = c.post("/dashboard/vms", json=body).json()
    print(f"\033[32mVM created: {result.get('id')} ({result.get('name')})\033[0m")


def cmd_vm_action(args):
    c = make_client(args.proxy, args.key)
    kwargs = {"json": {}}
    if args.action == "stop":
        kwargs["params"] = {"force": getattr(args, "force", False)}
    response = c.post(f"/dashboard/vms/{args.vm_id}/{args.action}", **kwargs)
    result = response.json()
    if result.get("ok"):
        print(f"\033[32mVM {args.vm_id}: {args.action} OK\033[0m")
    else:
        detail = result.get("detail") or f"{args.action} failed"
        print(f"\033[31mVM {args.vm_id}: {detail}\033[0m")
        raise SystemExit(1)


def cmd_vm_switch(args):
    c = make_client(args.proxy, args.key)
    result = c.post(f"/dashboard/vms/{args.vm_id}/switch-project",
                    json={"project_path": args.project}).json()
    if result.get("ok"):
        print(f"\033[32mVM {args.vm_id}: switched to {args.project}\033[0m")
    else:
        print("\033[31mFailed to switch project\033[0m")


def cmd_vm_open(args):
    """Open SPICE viewer for a VM (virt-viewer)."""
    vm_id = args.vm_id
    print(f"Opening SPICE viewer for {vm_id}...")
    try:
        subprocess.Popen(["virt-viewer", "--connect", "qemu:///session", vm_id],
                         stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
    except FileNotFoundError:
        print("\033[31mvirt-viewer not found. Install: sudo apt install virt-viewer\033[0m")
        sys.exit(1)


def _find_vm(args):
    """Look up a VM by ID or name, return dict or exit."""
    c = make_client(args.proxy, args.key)
    data = c.get("/dashboard/vms").json()
    vms = data.get("vms", [])
    target = next((v for v in vms if v["id"] == args.vm_id or v["name"] == args.vm_id), None)
    if not target:
        print(f"\033[31mVM '{args.vm_id}' not found\033[0m")
        sys.exit(1)
    ip = target.get("ip", "")
    if not ip:
        print(f"\033[31mVM '{args.vm_id}' has no IP address (not running?)\033[0m")
        sys.exit(1)
    return target, ip


def cmd_vm_ssh(args):
    """SSH into a VM (auto-detect IP via dashboard)."""
    _, ip = _find_vm(args)
    user = args.user or "dev"
    os.execvp("ssh", ["ssh", "-o", "StrictHostKeyChecking=no", f"{user}@{ip}"])


def cmd_vm_logs(args):
    """Show cloud-init logs and tool logs from a VM."""
    _, ip = _find_vm(args)
    user = "dev"
    cmd = "tail -n 100 /var/log/cloud-init-output.log 2>/dev/null || echo 'No cloud-init log'"
    os.execvp("ssh", ["ssh", "-o", "StrictHostKeyChecking=no", f"{user}@{ip}", cmd])


def cmd_vm_delete(args):
    """Delete a VM."""
    c = make_client(args.proxy, args.key)
    vm_id = args.vm_id
    response = c.delete(f"/dashboard/vms/{vm_id}")
    if response.status_code == 200:
        print(f"\033[32mVM {vm_id} deleted\033[0m")
    elif response.status_code == 404:
        print(f"\033[31mVM '{vm_id}' not found\033[0m")
        sys.exit(1)
    else:
        print(f"\033[31mFailed to delete VM {vm_id}: {response.status_code}\033[0m")
        sys.exit(1)


def cmd_vm_console(args):
    """Open web console for a VM (prints noVNC URL)."""
    import webbrowser
    c = make_client(args.proxy, args.key)
    response = c.get(f"/api/v1/vms/{args.vm_id}/console")
    if response.status_code == 404:
        print(f"\033[31mVM '{args.vm_id}' not found.\033[0m")
        sys.exit(1)
    if response.status_code == 409:
        print(f"\033[31mVM '{args.vm_id}' is not running.\033[0m")
        sys.exit(1)
    data = response.json()
    url = data.get("novnc_url", "")
    proxy_url = f"http://{c._base_url.host}:{c._base_url.port}" if hasattr(c, '_base_url') else ""
    full_url = f"{proxy_url}{url}" if url.startswith("/") else url
    print(f"  VM console: {full_url}")
    if full_url:
        try:
            webbrowser.open(full_url)
        except Exception:
            pass


def cmd_vm_bulk_delete(args):
    """Delete multiple VMs."""
    c = make_client(args.proxy, args.key)
    vm_ids = [v.strip() for v in args.vm_ids.split(",") if v.strip()]
    if not vm_ids:
        print("No VM IDs specified.")
        return
    response = c.post("/dashboard/vms/bulk-delete", json=vm_ids)
    result = response.json()
    deleted = result.get("deleted", [])
    failed = result.get("failed", [])
    if deleted:
        print(f"\033[32mDeleted: {', '.join(deleted)}\033[0m")
    if failed:
        print(f"\033[31mFailed: {', '.join(failed)}\033[0m")
