"""
Authentication decorators for role-based access control
"""
import jwt
from functools import wraps
from flask import request, jsonify, current_app
from models.user import Admin

# Superadmin credentials (should be in env vars in production)
SUPERADMIN_EMAIL = 'regmibishal964@gmail.com'

def token_required(f):
    """
    Decorator that validates JWT token and extracts user info.
    Passes current_user, user_role, institute_id, instructor_id to the route.
    """
    @wraps(f)
    def decorated(*args, **kwargs):
        token = request.headers.get('x-access-token')

        if not token:
            return jsonify({'message': 'Token is missing!'}), 401

        try:
            data = jwt.decode(token, current_app.config['SECRET_KEY'], algorithms=["HS256"])
            user_role = data.get('role')
            public_id = data['public_id']
            institute_id = data.get('institute_id')
            instructor_id = data.get('instructor_id')

            # For superadmin, create a dummy Admin object
            if public_id == 'superadmin' and user_role == 'superadmin':
                current_user = Admin(
                    public_id='superadmin', 
                    name='Super Admin', 
                    email=SUPERADMIN_EMAIL, 
                    role='superadmin'
                )
                
                # Check for context switch header
                context_institute_id = request.headers.get('x-institute-id')
                if context_institute_id:
                    try:
                        institute_id = int(context_institute_id)
                    except ValueError:
                        institute_id = None
                else:
                    institute_id = None
                    
                current_user.institute_id = institute_id
                current_user.instructor_id = None
            else:
                current_user = Admin.query.filter_by(public_id=public_id).first()
            
            if not current_user:
                return jsonify({'message': 'User not found after token validation!'}), 401

        except jwt.ExpiredSignatureError:
            return jsonify({'message': 'Token has expired!'}), 401
        except jwt.InvalidTokenError:
            return jsonify({'message': 'Token is invalid!'}), 401
        except Exception as e:
            return jsonify({'message': f'Token processing error: {str(e)}'}), 401

        # Pass user info to the decorated function
        return f(current_user, user_role, institute_id, instructor_id, *args, **kwargs)
    return decorated


def role_required(*allowed_roles):
    """
    Decorator to restrict route access to specific roles.
    Usage: @role_required('superadmin', 'institute_admin')
    Must be used AFTER @token_required
    """
    def decorator(f):
        @wraps(f)
        def decorated(current_user, user_role, institute_id, instructor_id, *args, **kwargs):
            if user_role not in allowed_roles:
                return jsonify({'error': 'Unauthorized. Required roles: ' + ', '.join(allowed_roles)}), 403
            return f(current_user, user_role, institute_id, instructor_id, *args, **kwargs)
        return decorated
    return decorator


def superadmin_required(f):
    """
    Shortcut decorator for superadmin-only routes.
    Must be used AFTER @token_required
    """
    @wraps(f)
    def decorated(current_user, user_role, institute_id, instructor_id, *args, **kwargs):
        if user_role != 'superadmin':
            return jsonify({'error': 'Superadmin access required'}), 403
        return f(current_user, user_role, institute_id, instructor_id, *args, **kwargs)
    return decorated


def institute_admin_required(f):
    """
    Decorator for routes that require institute admin or higher.
    Allows: superadmin, institute_admin, institute_owner
    Must be used AFTER @token_required
    """
    @wraps(f)
    def decorated(current_user, user_role, institute_id, instructor_id, *args, **kwargs):
        allowed = ['superadmin', 'institute_admin', 'institute_owner']
        if user_role not in allowed:
            return jsonify({'error': 'Institute admin access required'}), 403
        return f(current_user, user_role, institute_id, instructor_id, *args, **kwargs)
    return decorated
