"""Centralised DRF exception handler — uniform error envelope.

Response shape::

    {
      "error": {
        "code": "validation_error",
        "message": "...",
        "details": { ... }   # field errors, etc.
      }
    }
"""

from __future__ import annotations

import logging
from typing import Any

from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import exception_handler as drf_exception_handler

logger = logging.getLogger("simorgh.api")


def api_exception_handler(exc: Exception, context: dict[str, Any]) -> Response | None:
    response = drf_exception_handler(exc, context)
    if response is None:
        logger.exception(
            "Unhandled API exception", extra={"context_view": str(context.get("view"))}
        )
        return Response(
            {"error": {"code": "server_error", "message": "An unexpected error occurred."}},
            status=status.HTTP_500_INTERNAL_SERVER_ERROR,
        )

    code = getattr(exc, "default_code", exc.__class__.__name__).lower()
    detail = response.data
    message = _extract_message(detail)

    response.data = {
        "error": {
            "code": code,
            "message": message,
            "details": detail if isinstance(detail, dict | list) else None,
        }
    }
    return response


def _extract_message(detail: Any) -> str:
    if isinstance(detail, str):
        return detail
    if isinstance(detail, list) and detail:
        return _extract_message(detail[0])
    if isinstance(detail, dict):
        for value in detail.values():
            return _extract_message(value)
    return "Request failed."
