"""VM endpoints for dashboard API."""
from __future__ import annotations

from fastapi import APIRouter, HTTPException
from pydantic import BaseModel

from proxym.virt import VMConfig, VMOrchestrator
from proxym.dashboard._shared import shared_vms as _vms

router = APIRouter(prefix="/vms", tags=["vms"])


# ── Pydantic models ──────────────────────────────────────────

class CreateVMReq(BaseModel):
    name: str
    account_id: str = ""
    tool: str = ""
    vcpus: int = 2
    memory_mb: int = 4096
    disk_gb: int = 20
    base_image: str = "fedora-40-dev"
    code_mount_host: str = ""


class SwitchProjectReq(BaseModel):
    project_path: str


# ── Endpoints ─────────────────────────────────────────────────

@router.get("")
async def list_vms():
    return {"vms": [
        {
            "id": s.id, "name": s.name, "state": s.state.value,
            "account_id": s.account_id, "tool": s.tool,
            "uptime": s.uptime_seconds, "ip": s.ip_address,
            "code_mount": s.code_mount,
            "memory_mb": s.memory_mb,
            "vcpus": s.vcpus,
            "disk_gb": s.disk_gb,
            "last_started_at": s.last_started_at,
            "created_at": s.created_at,
        }
        for s in _vms().list_vms()
    ]}


@router.post("")
async def create_vm(req: CreateVMReq):
    config = VMConfig(
        name=req.name,
        account_id=req.account_id,
        tool=req.tool,
        vcpus=req.vcpus,
        memory_mb=req.memory_mb,
        disk_gb=req.disk_gb,
        base_image=req.base_image,
        code_mount_host=req.code_mount_host,
    )
    vm = _vms().create_vm(config)
    return {"id": vm.id, "name": vm.name, "state": vm.state.value}


@router.post("/{vm_id}/start")
async def start_vm(vm_id: str):
    vms = _vms()
    vm = vms.vms.get(vm_id)
    if not vm:
        raise HTTPException(404, f"VM '{vm_id}' not found")

    libvirt = VMOrchestrator.check_libvirt_available()
    if not libvirt.get("libvirt"):
        raise HTTPException(
            503,
            "Libvirt is not available on this host. VM actions require virsh/libvirt to be installed and running.",
        )

    try:
        success = vms.start_vm(vm_id)
        if success:
            return {"ok": True, "vm_id": vm_id, "state": "running"}
        backend = getattr(vm, "backend", "unknown")
        raise HTTPException(
            500,
            f"Failed to start VM '{vm_id}' (backend={backend}). Check server logs for details.",
        )
    except RuntimeError as e:
        raise HTTPException(
            409,
            {
                "error": str(e),
                "hint": "Delete and re-create the VM (config exists, libvirt domain missing).",
            },
        )
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(500, f"Failed to start VM: {e}")


@router.post("/{vm_id}/stop")
async def stop_vm(vm_id: str, force: bool = False):
    if _vms().stop_vm(vm_id, force=force):
        return {"ok": True}
    raise HTTPException(500, "Failed to stop VM")


@router.post("/{vm_id}/pause")
async def pause_vm(vm_id: str):
    if _vms().pause_vm(vm_id):
        return {"ok": True}
    raise HTTPException(500, "Failed to pause VM")


@router.post("/{vm_id}/resume")
async def resume_vm(vm_id: str):
    if _vms().resume_vm(vm_id):
        return {"ok": True}
    raise HTTPException(500, "Failed to resume VM")


@router.post("/{vm_id}/snapshot")
async def snapshot_vm(vm_id: str, name: str = ""):
    if _vms().snapshot_vm(vm_id, name):
        return {"ok": True}
    raise HTTPException(500, "Failed to create snapshot")


@router.post("/{vm_id}/switch-project")
async def switch_project(vm_id: str, req: SwitchProjectReq):
    if _vms().switch_project(vm_id, req.project_path):
        return {"ok": True}
    raise HTTPException(500, "Failed to switch project")


@router.delete("/{vm_id}")
async def delete_vm(vm_id: str):
    from proxym.dashboard.utils.delete_milestone import delete_vm
    return delete_vm(_vms().delete_vm, vm_id)


@router.post("/{vm_id}/delete")
async def delete_vm_post(vm_id: str):
    """POST variant for single VM deletion (matches frontend convention)."""
    from proxym.dashboard.utils.delete_milestone import delete_vm
    return delete_vm(_vms().delete_vm, vm_id)


@router.post("/bulk-delete")
async def bulk_delete_vms(req: list[str]):
    """Delete multiple VMs by their IDs. Returns list of successfully deleted VM IDs."""
    deleted = []
    failed = []
    for vm_id in req:
        try:
            if _vms().delete_vm(vm_id):
                deleted.append(vm_id)
            else:
                failed.append(vm_id)
        except Exception:
            failed.append(vm_id)
    return {"deleted": deleted, "failed": failed, "total_requested": len(req)}
