"""HTTP client wrapper for HAX API."""

from __future__ import annotations

from typing import Any

import httpx

from hax.exceptions import (
    AuthenticationError,
    HaxError,
    NotFoundError,
    RateLimitError,
    ServerError,
    ValidationError,
)

DEFAULT_TIMEOUT = 30.0


class HttpClient:
    """HTTP client wrapper with authentication and error handling."""

    def __init__(
        self,
        api_key: str,
        base_url: str,
        timeout: float = DEFAULT_TIMEOUT,
    ) -> None:
        self._api_key = api_key
        self._base_url = base_url.rstrip("/")
        self._client = httpx.Client(
            base_url=self._base_url,
            timeout=timeout,
            headers={
                "Authorization": f"Bearer {api_key}",
                "Content-Type": "application/json",
                "User-Agent": "hax-python-sdk/0.1.0",
            },
        )

    def _handle_error_response(self, response: httpx.Response) -> None:
        """Raise appropriate exception for error responses."""
        try:
            data = response.json()
            message = data.get("error", response.reason_phrase or "Unknown error")
            details = data.get("details")
        except Exception:
            message = response.reason_phrase or "Unknown error"
            details = None

        status = response.status_code

        if status == 401:
            raise AuthenticationError(message, details)
        elif status == 404:
            raise NotFoundError(message, details)
        elif status == 422:
            raise ValidationError(message, details)
        elif status == 429:
            retry_after = response.headers.get("Retry-After")
            raise RateLimitError(
                message,
                retry_after=int(retry_after) if retry_after else None,
                details=details,
            )
        elif status >= 500:
            raise ServerError(message, status_code=status, details=details)
        else:
            raise HaxError(f"HTTP {status}: {message}", details)

    def get(self, path: str, params: dict[str, Any] | None = None) -> dict[str, Any]:
        """Make a GET request."""
        response = self._client.get(path, params=params)
        if not response.is_success:
            self._handle_error_response(response)
        return response.json()  # type: ignore[no-any-return]

    def post(
        self, path: str, json: dict[str, Any] | None = None
    ) -> dict[str, Any]:
        """Make a POST request."""
        response = self._client.post(path, json=json)
        if not response.is_success:
            self._handle_error_response(response)
        return response.json()  # type: ignore[no-any-return]

    def patch(
        self, path: str, json: dict[str, Any] | None = None
    ) -> dict[str, Any]:
        """Make a PATCH request."""
        response = self._client.patch(path, json=json)
        if not response.is_success:
            self._handle_error_response(response)
        return response.json()  # type: ignore[no-any-return]

    def delete(self, path: str) -> dict[str, Any] | None:
        """Make a DELETE request."""
        response = self._client.delete(path)
        if not response.is_success:
            self._handle_error_response(response)
        if response.content:
            return response.json()  # type: ignore[no-any-return]
        return None

    def close(self) -> None:
        """Close the HTTP client."""
        self._client.close()

    def __enter__(self) -> HttpClient:
        return self

    def __exit__(self, *args: Any) -> None:
        self.close()
