from __future__ import annotations
import uuid, traceback
from django.conf import settings
from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework.response import Response
from rest_framework import status
from rest_framework.exceptions import ValidationError as DRFValidationError
from pydantic import ValidationError as PydValidationError

def envelope_exception_handler(exc, context):
    """
    Envuelve *todas* las excepciones DRF en:
    { ok: false, code, message, errors?, hint?, trace_id, detail?(DEBUG) }
    """
    resp = drf_exception_handler(exc, context)
    trace_id = str(uuid.uuid4())

    if resp is not None:
        # DRF ya resolvió un status_code razonable
        code = getattr(exc, "default_code", "error")
        message = None

        if isinstance(exc, DRFValidationError):
            message = "Validation error"
        else:
            # fallback a string corto
            message = str(getattr(exc, "detail", "")) or exc.__class__.__name__

        data = {
            "ok": False,
            "code": code,
            "message": message,
            "errors": resp.data,   # DRF normaliza los errores aquí
            "hint": None,
            "trace_id": trace_id,
        }
        if settings.DEBUG:
            data["detail"] = _short_trace()
        return Response(data, status=resp.status_code)

    # Excepción no manejada por DRF -> 500
    data = {
        "ok": False,
        "code": "server_error",
        "message": "Unexpected server error",
        "hint": None,
        "trace_id": trace_id,
    }
    if settings.DEBUG:
        data["detail"] = _short_trace()
    return Response(data, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

def _short_trace():
    try:
        return "\n".join(traceback.format_exc().splitlines()[-6:])
    except Exception:
        return None
