"""Thin HTTP client for the control plane API."""
from __future__ import annotations

from typing import Any

import httpx


class ApiError(RuntimeError):
    def __init__(self, status: int, message: str) -> None:
        self.status = status
        super().__init__(f"API {status}: {message}")


class ControlPlaneClient:
    def __init__(self, api_url: str, token: str | None = None) -> None:
        self.api_url = api_url.rstrip("/")
        self.token = token

    def _headers(self) -> dict[str, str]:
        h = {"content-type": "application/json"}
        if self.token:
            h["authorization"] = f"bearer {self.token}"
        return h

    def _request(self, method: str, path: str, **kw: Any) -> Any:
        url = f"{self.api_url}{path}"
        with httpx.Client(timeout=30.0) as c:
            resp = c.request(method, url, headers=self._headers(), **kw)
        if resp.status_code >= 400:
            try:
                detail = resp.json().get("detail", resp.text)
            except Exception:  # noqa: BLE001
                detail = resp.text
            raise ApiError(resp.status_code, str(detail))
        if resp.status_code == 204 or not resp.content:
            return None
        return resp.json()

    def signup(self, email: str, password: str) -> dict[str, Any]:
        return self._request("POST", "/v1/auth/signup", json={"email": email, "password": password})

    def login(self, email: str, password: str) -> dict[str, Any]:
        return self._request("POST", "/v1/auth/login", json={"email": email, "password": password})

    def me(self) -> dict[str, Any]:
        return self._request("GET", "/v1/me")

    def register_agent(
        self,
        *,
        name: str,
        description: str,
        version: str,
        image: str,
        public: bool,
        card: dict[str, Any],
    ) -> dict[str, Any]:
        return self._request(
            "POST",
            "/v1/agents",
            json={
                "name": name,
                "description": description,
                "version": version,
                "image": image,
                "public": public,
                "card": card,
            },
        )

    def from_source(
        self,
        *,
        name: str,
        description: str,
        version: str,
        public: bool,
    ) -> dict[str, Any]:
        return self._request(
            "POST",
            "/v1/agents/from-source",
            json={
                "name": name,
                "description": description,
                "version": version,
                "public": public,
            },
        )

    def from_tarball(
        self,
        *,
        name: str,
        version: str,
        entrypoint: str,
        description: str,
        public: bool,
        tarball: bytes,
    ) -> dict[str, Any]:
        with httpx.Client(timeout=120.0) as c:
            resp = c.post(
                f"{self.api_url}/v1/agents/from-tarball",
                headers={"authorization": f"bearer {self.token}"} if self.token else {},
                data={
                    "name": name,
                    "version": version,
                    "entrypoint": entrypoint,
                    "description": description,
                    "public": str(public).lower(),
                },
                files={"source": ("source.tar.gz", tarball, "application/gzip")},
            )
        if resp.status_code >= 400:
            try:
                detail = resp.json().get("detail", resp.text)
            except Exception:  # noqa: BLE001
                detail = resp.text
            raise ApiError(resp.status_code, str(detail))
        return resp.json()

    def list_agents(self) -> list[dict[str, Any]]:
        return self._request("GET", "/v1/agents")

    def get_agent(self, name: str) -> dict[str, Any]:
        return self._request("GET", f"/v1/agents/{name}")

    def delete_agent(self, name: str) -> None:
        self._request("DELETE", f"/v1/agents/{name}")
