"""HTTP transport layer for payment API requests."""

import time
from typing import Any

import httpx

from payelink_agent_pay.config import ClientConfig
from payelink_agent_pay.errors import PaymentAPIError, PaymentError, PaymentTimeoutError


class HTTPTransport:
    """HTTP client wrapper for payment API requests."""

    def __init__(self, config: ClientConfig):
        """Initialize the HTTP transport with configuration.

        Args:
            config: Client configuration
        """
        self.config = config
        self.client = httpx.Client(
            base_url=str(config.base_url),
            timeout=config.timeout,
            verify=config.verify_ssl,
            headers={
                "Authorization": f"Bearer {config.api_key}",
                "Content-Type": "application/json",
                "User-Agent": "payelink-agent-pay-sdk",
            },
        )

    def request(
        self,
        method: str,
        path: str,
        json: dict[str, Any] | None = None,
        params: dict[str, Any] | None = None,
    ) -> dict[str, Any]:
        """Make an HTTP request with retry logic.

        Args:
            method: HTTP method (GET, POST, etc.)
            path: API endpoint path
            json: JSON payload for request body
            params: Query parameters

        Returns:
            Response JSON data

        Raises:
            PaymentAPIError: If the API returns an error
            PaymentTimeoutError: If the request times out
            PaymentError: For other transport errors
        """
        last_exception: Exception | None = None

        for attempt in range(self.config.max_retries + 1):
            try:
                response = self.client.request(
                    method=method,
                    url=path,
                    json=json,
                    params=params,
                )
                response.raise_for_status()
                return response.json()

            except httpx.TimeoutException as e:
                last_exception = e
                if attempt < self.config.max_retries:
                    time.sleep(self.config.retry_delay * (attempt + 1))
                    continue
                raise PaymentTimeoutError(
                    f"Request timed out after {self.config.timeout}s",
                    status_code=None,
                ) from e

            except httpx.HTTPStatusError as e:
                error_data = {}
                try:
                    error_data = e.response.json()
                except Exception:
                    pass

                error_message = error_data.get("message", e.response.text or str(e))
                error_code = error_data.get("error_code")

                raise PaymentAPIError(
                    message=error_message,
                    status_code=e.response.status_code,
                    error_code=error_code,
                ) from e

            except httpx.RequestError as e:
                last_exception = e
                if attempt < self.config.max_retries:
                    time.sleep(self.config.retry_delay * (attempt + 1))
                    continue
                raise PaymentError(
                    f"Request failed: {str(e)}",
                    status_code=None,
                ) from e

        # This should never be reached, but type checker needs it
        if last_exception:
            raise PaymentError(
                f"Request failed after {self.config.max_retries + 1} attempts: {str(last_exception)}",
                status_code=None,
            ) from last_exception

        raise PaymentError("Request failed for unknown reason", status_code=None)

    def get(self, path: str, params: dict[str, Any] | None = None) -> dict[str, Any]:
        """Make a GET request.

        Args:
            path: API endpoint path
            params: Query parameters

        Returns:
            Response JSON data
        """
        return self.request("GET", path, params=params)

    def post(self, path: str, json: dict[str, Any] | None = None) -> dict[str, Any]:
        """Make a POST request.

        Args:
            path: API endpoint path
            json: JSON payload

        Returns:
            Response JSON data
        """
        return self.request("POST", path, json=json)

    def patch(self, path: str, json: dict[str, Any] | None = None) -> dict[str, Any]:
        """Make a PATCH request.

        Args:
            path: API endpoint path
            json: JSON payload

        Returns:
            Response JSON data
        """
        return self.request("PATCH", path, json=json)

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

    def __enter__(self) -> "HTTPTransport":
        """Context manager entry."""
        return self

    def __exit__(self, exc_type, exc_val, exc_tb) -> None:
        """Context manager exit."""
        self.close()
