"""
PREPOC ERP — Custom Exception Handler
"""
import logging

from django.core.exceptions import ValidationError as DjangoValidationError
from rest_framework import status
from rest_framework.exceptions import ValidationError
from rest_framework.response import Response
from rest_framework.views import exception_handler

logger = logging.getLogger("prepoc")


def custom_exception_handler(exc, context):
    """
    Custom DRF exception handler that returns consistent error responses:

    {
        "success": false,
        "error": {
            "code": "validation_error",
            "message": "...",
            "details": {...}
        }
    }
    """
    # Convert Django ValidationError to DRF ValidationError
    if isinstance(exc, DjangoValidationError):
        exc = ValidationError(detail=exc.message_dict if hasattr(exc, "message_dict") else exc.messages)

    response = exception_handler(exc, context)

    if response is not None:
        error_data = {
            "success": False,
            "error": {
                "code": _get_error_code(exc),
                "message": _get_error_message(response.data),
                "details": response.data,
            },
        }
        response.data = error_data

        # Log server errors
        if response.status_code >= 500:
            logger.error(
                "Server error in %s: %s",
                context.get("view", "unknown"),
                exc,
                exc_info=True,
            )

    return response


def _get_error_code(exc) -> str:
    code_map = {
        "AuthenticationFailed": "authentication_failed",
        "NotAuthenticated": "not_authenticated",
        "PermissionDenied": "permission_denied",
        "NotFound": "not_found",
        "MethodNotAllowed": "method_not_allowed",
        "ValidationError": "validation_error",
        "Throttled": "rate_limit_exceeded",
    }
    return code_map.get(type(exc).__name__, "server_error")


def _get_error_message(data) -> str:
    if isinstance(data, list) and data:
        item = data[0]
        return str(item) if not hasattr(item, "detail") else str(item.detail)
    if isinstance(data, dict):
        for key, val in data.items():
            if key != "detail":
                return f"{key}: {_get_error_message(val)}"
        return str(data.get("detail", "An error occurred."))
    return str(data)
