# principal/permisos.py - Decoradores y funciones de control de acceso basado en roles
from functools import wraps
from django.shortcuts import redirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required


def require_role(*roles):
    """
    Decorador que requiere que el usuario tenga uno de los roles especificados.
    Los administradores siempre tienen acceso.
    
    Uso:
        @require_role('admin', 'director')
        def mi_vista(request):
            pass
    """
    def decorator(view_func):
        @wraps(view_func)
        @login_required(login_url='login')
        def wrapper(request, *args, **kwargs):
            # Admin tiene acceso a todo
            if request.user.rol == 'admin':
                return view_func(request, *args, **kwargs)
            
            # Verificar si el usuario tiene uno de los roles requeridos
            if request.user.rol in roles:
                return view_func(request, *args, **kwargs)
            
            # Acceso denegado
            messages.error(request, f'No tienes permiso para acceder a esta página. Se requiere rol: {", ".join(roles)}')
            return redirect('muro')
        
        return wrapper
    return decorator


def require_any_role(*roles):
    """Alias para require_role - requiere cualquiera de los roles listados"""
    return require_role(*roles)


def allow_role(*roles):
    """
    Decorador que solo permite que ciertos roles accedan (y niega a administrador si se especifica).
    Útil para vistas específicas de roles.
    
    Uso:
        @allow_role('campamentista')
        def mi_vista_campamentista(request):
            pass
    """
    def decorator(view_func):
        @wraps(view_func)
        @login_required(login_url='login')
        def wrapper(request, *args, **kwargs):
            if request.user.rol in roles:
                return view_func(request, *args, **kwargs)
            
            messages.error(request, 'No tienes permiso para acceder a esta página.')
            return redirect('muro')
        
        return wrapper
    return decorator


# Decoradores específicos por rol
def admin_only(view_func):
    """Solo administradores pueden acceder"""
    return require_role('admin')(view_func)


def director_or_admin(view_func):
    """Solo directores y administradores"""
    return require_role('director', 'admin')(view_func)


def inscripcion_or_admin(view_func):
    """Solo personal de inscripción y administradores"""
    return require_role('inscripcion', 'admin')(view_func)


def lider_or_higher(view_func):
    """Líderes, directores y administradores"""
    return require_role('lider', 'director', 'admin')(view_func)


def pastor_or_admin(view_func):
    """Pastores y administradores"""
    return require_role('pastor', 'admin')(view_func)


def authenticated_only(view_func):
    """Solo usuarios autenticados (todos los roles)"""
    @wraps(view_func)
    @login_required(login_url='login')
    def wrapper(request, *args, **kwargs):
        return view_func(request, *args, **kwargs)
    return wrapper


# Funciones auxiliares para verificación de permisos en plantillas
def user_can_edit_actividades(user):
    """Verifica si el usuario puede crear/editar actividades"""
    return user.rol in ('lider', 'director', 'admin')


def user_can_edit_noticias(user):
    """Verifica si el usuario puede crear/editar noticias"""
    return user.rol in ('lider', 'director', 'admin')


def user_can_edit_puntos(user):
    """Verifica si el usuario puede gestionar puntos"""
    return user.rol in ('director', 'admin')


def user_can_edit_inventario(user):
    """Verifica si el usuario puede editar inventario"""
    return user.rol in ('inscripcion', 'admin')


def user_can_crear_devocionales(user):
    """Verifica si el usuario puede crear devocionales"""
    return user.rol in ('pastor', 'admin')


def user_is_admin(user):
    """Verifica si el usuario es administrador"""
    return user.rol == 'admin'


def user_is_director(user):
    """Verifica si el usuario es director"""
    return user.rol in ('director', 'admin')


# Contexto de permisos para plantillas
def get_context_permisos(user):
    """
    Retorna un diccionario con los permisos del usuario para usar en plantillas.
    
    Uso en view:
        contexto['permisos'] = get_context_permisos(request.user)
    
    Uso en template:
        {% if permisos.puede_editar_actividades %}...{% endif %}
    """
    if not user.is_authenticated:
        return {
            'puede_ver_muro': False,
            'puede_editar_actividades': False,
            'puede_editar_noticias': False,
            'puede_editar_puntos': False,
            'puede_editar_inventario': False,
            'puede_crear_devocionales': False,
            'es_admin': False,
            'es_director': False,
        }
    
    return {
        'puede_ver_muro': True,  # Todos ven el muro
        'puede_editar_actividades': user_can_edit_actividades(user),
        'puede_editar_noticias': user_can_edit_noticias(user),
        'puede_editar_puntos': user_can_edit_puntos(user),
        'puede_editar_inventario': user_can_edit_inventario(user),
        'puede_crear_devocionales': user_can_crear_devocionales(user),
        'es_admin': user_is_admin(user),
        'es_director': user_is_director(user),
        'rol': user.rol,
    }
