"""Shared HTTP response handling for Miruvor.

This module intentionally uses duck-typing so it works for both `requests` and `httpx`
responses without extra dependencies.
"""

from typing import Any

from .exceptions import (
    AuthenticationError,
    AuthorizationError,
    MiruvorError,
    NotFoundError,
    RateLimitError,
    ServerError,
    ValidationError,
)


def parse_json_or_raise(response: Any) -> Any:
    """Return JSON on success; raise MiruvorError on non-2xx."""
    status = int(getattr(response, "status_code", 0) or 0)
    if status in (200, 201):
        return response.json()

    message = _extract_message(response)

    if status == 401:
        raise AuthenticationError(message, status, response)
    if status == 403:
        raise AuthorizationError(message, status, response)
    if status == 404:
        raise NotFoundError(message, status, response)
    if status == 422:
        raise ValidationError(message, status, response)
    if status == 429:
        raise RateLimitError(message, status, response)
    if status >= 500:
        raise ServerError(message, status, response)
    raise MiruvorError(message, status, response)


def _extract_message(response: Any) -> str:
    try:
        payload = response.json()
        if isinstance(payload, dict) and "detail" in payload:
            return str(payload.get("detail"))
    except (ValueError, TypeError):
        pass
    return str(getattr(response, "text", "") or "")

