"""Appliance health / networking / timesync — mutable lab state."""

from __future__ import annotations

from typing import Any

from fastapi import APIRouter, Depends

from app.db.pool import Database
from app.dependencies import get_database
from app.vsphere.domain import appliance
from app.vsphere.errors import invalid_argument
from app.vsphere.security.authz import require_admin, require_read
from app.vsphere.security.session import SessionInfo

router = APIRouter(tags=["vSphere Appliance"])


@router.get("/api/appliance/health/system")
async def health_system(
    database: Database = Depends(get_database),
    _: SessionInfo = Depends(require_read),
) -> dict[str, Any]:
    from app.vsphere.domain import api_state

    payload = await api_state.get_payload(database, "GET", "/api/appliance/health/system")
    return payload if isinstance(payload, dict) else {"status": "unknown", "messages": []}


@router.get("/api/appliance/networking")
async def networking(
    database: Database = Depends(get_database),
    _: SessionInfo = Depends(require_read),
) -> dict[str, Any]:
    return await appliance.get_networking(database)


@router.get("/api/appliance/networking/dns/hostname")
async def get_dns_hostname(
    database: Database = Depends(get_database),
    _: SessionInfo = Depends(require_read),
) -> dict[str, str]:
    return {"name": await appliance.get_hostname(database)}


@router.put("/api/appliance/networking/dns/hostname")
@router.post("/api/appliance/networking/dns/hostname")
async def set_dns_hostname(
    body: dict[str, Any],
    database: Database = Depends(get_database),
    _: SessionInfo = Depends(require_admin),
) -> dict[str, str]:
    name = str(body.get("name") or body.get("hostname") or "").strip()
    if not name:
        raise invalid_argument("name is required")
    hostname = await appliance.set_hostname(database, name)
    return {"name": hostname}


@router.get("/api/appliance/networking/dns/servers")
async def get_dns_servers(
    database: Database = Depends(get_database),
    _: SessionInfo = Depends(require_read),
) -> dict[str, Any]:
    networking_state = await appliance.get_networking(database)
    dns = networking_state.get("dns") or {}
    return {"mode": dns.get("mode"), "servers": list(dns.get("servers") or [])}


@router.put("/api/appliance/networking/dns/servers")
@router.post("/api/appliance/networking/dns/servers")
async def set_dns_servers(
    body: dict[str, Any],
    database: Database = Depends(get_database),
    _: SessionInfo = Depends(require_admin),
) -> dict[str, Any]:
    mode = body.get("mode")
    servers = body.get("servers")
    if servers is None and body.get("server"):
        servers = [body["server"]]
    return await appliance.set_dns_servers(
        database,
        mode=str(mode) if mode is not None else None,
        servers=[str(s) for s in servers] if isinstance(servers, list) else None,
    )


@router.get("/api/appliance/networking/dns/domains")
async def get_dns_domains(
    database: Database = Depends(get_database),
    _: SessionInfo = Depends(require_read),
) -> list[str]:
    networking_state = await appliance.get_networking(database)
    dns = networking_state.get("dns") or {}
    return list(dns.get("domains") or [])


@router.put("/api/appliance/networking/dns/domains")
@router.post("/api/appliance/networking/dns/domains")
async def set_dns_domains(
    body: dict[str, Any] | list[Any],
    database: Database = Depends(get_database),
    _: SessionInfo = Depends(require_admin),
) -> list[str]:
    if isinstance(body, list):
        domains = [str(d) for d in body]
    else:
        domains = [str(d) for d in (body.get("domains") or body.get("domain") or [])]
        if isinstance(body.get("domain"), str):
            domains = [str(body["domain"])]
    if not domains:
        from app.vsphere.errors import invalid_argument

        raise invalid_argument("domains is required")
    return await appliance.set_dns_domains(database, domains)


@router.get("/api/appliance/timesync")
async def timesync(
    database: Database = Depends(get_database),
    _: SessionInfo = Depends(require_read),
) -> dict[str, Any]:
    return await appliance.get_timesync(database)
