"""
shared/utils/exception_handler.py
===================================
Handler global de excepciones para DRF.
Convierte TODOS los errores al formato estándar de respuesta de la API.

Sin esto, DRF retorna formatos inconsistentes según el tipo de error.
Con esto, el frontend siempre recibe { success: false, message, errors }.
"""

import logging
from rest_framework.views import exception_handler
from rest_framework.response import Response
from rest_framework import status

logger = logging.getLogger('eduplay')


def custom_exception_handler(exc, context):
    """
    Handler personalizado que extiende el de DRF.
    
    Flujo:
      1. Llama al handler original de DRF
      2. Si hay respuesta, la reformatea al estándar
      3. Si no hay respuesta (error 500), retorna error genérico
    """
    # Llamar al handler original de DRF primero
    response = exception_handler(exc, context)

    if response is not None:
        # Reformatear respuesta existente de DRF
        error_data = {
            'success': False,
            'message': _extract_message(response.data),
            'data': None,
            'errors': response.data if isinstance(response.data, dict) else None,
        }
        response.data = error_data
    else:
        # Error no manejado por DRF (ej: error de BD, excepción Python)
        logger.exception(f'Error no manejado: {exc}', exc_info=exc)
        response = Response({
            'success': False,
            'message': 'Error interno del servidor. Por favor contacta al administrador.',
            'data': None,
            'errors': None,
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    return response


def _extract_message(data) -> str:
    """
    Extrae un mensaje legible de los datos de error de DRF.
    DRF puede retornar str, list o dict según el tipo de error.
    """
    if isinstance(data, str):
        return data
    if isinstance(data, list) and data:
        return str(data[0])
    if isinstance(data, dict):
        # Buscar campos comunes de error
        for key in ('detail', 'message', 'non_field_errors'):
            if key in data:
                val = data[key]
                return str(val[0]) if isinstance(val, list) else str(val)
        # Tomar el primer campo disponible
        first_key = next(iter(data))
        val = data[first_key]
        return f"{first_key}: {str(val[0]) if isinstance(val, list) else str(val)}"
    return 'Error desconocido'
