"""BlackAnt SDK HTTP communication module.

HTTP client with Bearer token authentication, request ID tracking,
and integration with auth store modules.
"""

import requests
from requests.adapters import HTTPAdapter

from ..auth.tokens import AuthTokenStore
from ..auth.request_id import RequestIdStore
from ..utils.logging import get_logger, set_request_id, clear_request_id


class HTTPConnectionError(Exception):
    """HTTP connection specific exception.

    Raised when HTTP requests fail due to connection issues,
    timeouts, or network problems.
    """


class HTTPClient:  # pylint: disable=too-few-public-methods
    """HTTP client for BlackAnt SDK API communication.

    Provides HTTP request functionality with automatic Bearer token injection,
    request ID tracking, and base URL management.

    Args:
        base_url (str): Base URL for API endpoints.
        auth_token_store (AuthTokenStore, optional): Token storage instance.
        request_id_store (RequestIdStore, optional): Request ID storage instance.

    Examples:
        >>> client = HTTPClient("https://api.blackant.app")
        >>> client.auth_token_store.user_token = "your_token"
        >>> response = client.send_request("/api/v1/services", "GET")
    """

    def __init__(self, base_url, auth_token_store=None, request_id_store=None):
        """Initialize HTTP client.

        Args:
            base_url (str): Base URL for API endpoints.
            auth_token_store (AuthTokenStore, optional): Token storage.
            request_id_store (RequestIdStore, optional): Request ID storage.
        """
        self.base_url = base_url.rstrip("/")
        self.auth_token_store = auth_token_store or AuthTokenStore()
        self.request_id_store = request_id_store or RequestIdStore()
        self.logger = get_logger("http")

        self.session = requests.Session()
        adapter = HTTPAdapter(pool_connections=10, pool_maxsize=20, max_retries=0)
        self.session.mount("https://", adapter)
        self.session.mount("http://", adapter)

    def send_request(  # pylint: disable=too-many-arguments
        self,
        endpoint,
        method,
        json=None,
        anonymous=False,
        is_admin=False,
        req_timeout=60.0,
        token=None,
    ):
        """Send HTTP request to the configured API endpoint.

        Args:
            endpoint (str): API endpoint path.
            method (str): HTTP method.
            json (dict, optional): JSON data for request body.
            anonymous (bool): Skip Bearer token authentication.
            is_admin (bool): Use admin token instead of user token.
            req_timeout (float): Request timeout in seconds.
            token (str, optional): Custom Bearer token.

        Returns:
            requests.Response: HTTP response object.

        Raises:
            HTTPConnectionError: When connection fails or times out.
        """
        request_id = self.request_id_store.generate_id()
        set_request_id(request_id)

        url = f"{self.base_url}/{endpoint.lstrip('/')}"

        try:
            req = requests.Request(method, url, json=json)
            prepped = self.session.prepare_request(req)

            if not anonymous:
                if token:
                    prepped.headers["Authorization"] = f"Bearer {token}"
                else:
                    auth_token = (
                        self.auth_token_store.admin_token if is_admin
                        else self.auth_token_store.user_token
                    )
                    if auth_token:
                        prepped.headers["Authorization"] = f"Bearer {auth_token}"

            prepped.headers[self.request_id_store.header_name] = request_id

            # Determine if we should verify SSL (skip for localhost/dev)
            verify_ssl = not (
                "localhost" in self.base_url or
                "127.0.0.1" in self.base_url or
                "http://" in url or  # HTTP doesn't need SSL verification
                "dev.blackant.app" in self.base_url  # Dev environment self-signed cert
            )

            response = self.session.send(prepped, timeout=req_timeout, verify=verify_ssl)
            return response

        except requests.exceptions.ConnectionError as exc:
            self.logger.error(f"Connection error: {exc}")
            raise HTTPConnectionError from exc
        except requests.exceptions.Timeout as exc:
            self.logger.error(f"Request time-out error: {exc}")
            raise HTTPConnectionError from exc
        finally:
            clear_request_id()
