import logging
from typing import Any, Dict, Optional

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

logger = logging.getLogger(__name__)

_session: Optional[requests.Session] = None


def _get_session() -> requests.Session:
    global _session
    if _session is not None:
        return _session

    session = requests.Session()
    retries = Retry(
        total=3,
        connect=3,
        read=3,
        backoff_factor=0.5,
        status_forcelist=(429, 500, 502, 503, 504),
        allowed_methods=frozenset(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]),
        raise_on_status=False,
    )
    adapter = HTTPAdapter(max_retries=retries)
    session.mount("http://", adapter)
    session.mount("https://", adapter)
    _session = session
    return session


def http_get(
    url: str,
    *,
    params: Optional[Dict[str, Any]] = None,
    headers: Optional[Dict[str, str]] = None,
    timeout: float = 15.0,
) -> requests.Response:
    """
    GET with sane defaults: retries, timeout, and basic logging.
    """
    session = _get_session()
    try:
        resp = session.get(url, params=params, headers=headers, timeout=timeout)
        return resp
    except Exception:
        logger.exception("HTTP GET failed: %s", url)
        raise


def http_post(
    url: str,
    *,
    json: Optional[Dict[str, Any]] = None,
    data: Optional[Dict[str, Any]] = None,
    headers: Optional[Dict[str, str]] = None,
    timeout: float = 20.0,
) -> requests.Response:
    session = _get_session()
    try:
        resp = session.post(url, json=json, data=data, headers=headers, timeout=timeout)
        return resp
    except Exception:
        logger.exception("HTTP POST failed: %s", url)
        raise

