"""PLS API client for cluster and per-node discovery."""

from __future__ import annotations

from urllib.parse import urlsplit, urlunsplit

import httpx

from app.config import PLS_AUTH_BACKEND, PLS_BASE_URL, PLS_PASSWORD, PLS_USERNAME, PLS_VERIFY_TLS

_token: str | None = None


def _base_url_for_host(host: str | None = None) -> str:
    if not host:
        return PLS_BASE_URL.rstrip("/")
    parts = urlsplit(PLS_BASE_URL)
    return urlunsplit((parts.scheme, host, parts.path.rstrip("/"), "", ""))


async def _login() -> str | None:
    global _token
    if _token:
        return _token
    if not PLS_USERNAME or not PLS_PASSWORD:
        return None

    try:
        async with httpx.AsyncClient(timeout=5, verify=PLS_VERIFY_TLS) as client:
            response = await client.post(
                f"{_base_url_for_host()}/auth/login",
                json={
                    "username": PLS_USERNAME,
                    "password": PLS_PASSWORD,
                    "backend": PLS_AUTH_BACKEND,
                },
            )
            response.raise_for_status()
            data = response.json()
            _token = data.get("access_token")
            return _token
    except Exception:
        return None


async def _get(path: str, host: str | None = None) -> dict | list | None:
    token = await _login()
    if not token:
        return None

    headers = {"Authorization": f"Bearer {token}"}
    url = f"{_base_url_for_host(host)}/{path.lstrip('/')}"
    try:
        async with httpx.AsyncClient(timeout=5, verify=PLS_VERIFY_TLS) as client:
            response = await client.get(url, headers=headers)
            response.raise_for_status()
            return response.json()
    except Exception:
        return None


def node_host(node_name: str) -> str:
    return node_name.split("@", 1)[1] if "@" in node_name else node_name


async def get_cluster_status() -> dict | None:
    data = await _get("data_layer/cluster/status")
    return data if isinstance(data, dict) else None


async def get_system_info(host: str | None = None) -> dict | None:
    data = await _get("system/info", host=host)
    return data if isinstance(data, dict) else None


async def get_services(host: str | None = None) -> list[dict]:
    data = await _get("services", host=host)
    return data if isinstance(data, list) else []
