from __future__ import annotations

from typing import Any

import httpx

from ._config import SurfinguardConfig
from ._version import __version__
from .exceptions import APIError, AuthenticationError, RateLimitError


class SurfinguardHTTPClient:
    """HTTP client wrapper with error mapping."""

    def __init__(self, config: SurfinguardConfig) -> None:
        self._config = config
        self._client = httpx.Client(
            base_url=config.base_url,
            timeout=config.timeout,
            headers={
                "Authorization": f"Bearer {config.api_key}",
                "Content-Type": "application/json",
                "User-Agent": f"surfinguard-python/{__version__}",
            },
        )

    def post(self, path: str, json: dict[str, Any]) -> dict[str, Any]:
        response = self._client.post(path, json=json)
        return self._handle_response(response)

    def get(self, path: str) -> dict[str, Any]:
        response = self._client.get(path)
        return self._handle_response(response)

    def put(self, path: str, json: dict[str, Any]) -> dict[str, Any]:
        response = self._client.put(path, json=json)
        return self._handle_response(response)

    def delete(self, path: str) -> dict[str, Any]:
        response = self._client.delete(path)
        return self._handle_response(response)

    def _handle_response(self, response: httpx.Response) -> dict[str, Any]:
        if response.status_code == 401:
            data = response.json()
            raise AuthenticationError(data.get("error", "Authentication failed"))

        if response.status_code == 429:
            retry_after = response.headers.get("Retry-After")
            data = response.json()
            raise RateLimitError(
                data.get("error", "Rate limit exceeded"),
                retry_after=int(retry_after) if retry_after else None,
            )

        if response.status_code >= 400:
            try:
                data = response.json()
                message = data.get("error", f"HTTP {response.status_code}")
            except Exception:
                message = f"HTTP {response.status_code}"
            raise APIError(message, status_code=response.status_code)

        return response.json()  # type: ignore[no-any-return]

    def close(self) -> None:
        self._client.close()
