"""
Standardized Permission Classes
Provides consistent permission checking across all endpoints
"""
from rest_framework import permissions
from rest_framework.exceptions import PermissionDenied


class IsAuthenticatedAndActive(permissions.BasePermission):
    """
    Permission class that requires user to be authenticated and active
    Base permission for most endpoints
    """
    def has_permission(self, request, view):
        if not request.user or not request.user.is_authenticated:
            return False
        
        # Check if user is active
        if hasattr(request.user, 'is_active'):
            return request.user.is_active
        
        return True


class HasTenantAccess(permissions.BasePermission):
    """
    Permission class that requires user to belong to the tenant/account
    Ensures tenant isolation
    Superusers, developers, and system account users bypass this check.
    """
    def has_permission(self, request, view):
        if not request.user or not request.user.is_authenticated:
            return False
        
        # Bypass for superusers
        if getattr(request.user, 'is_superuser', False):
            return True
        
        # Bypass for developers
        if hasattr(request.user, 'role') and request.user.role == 'developer':
            return True
        
        # Bypass for system account users
        try:
            if hasattr(request.user, 'is_system_account_user') and request.user.is_system_account_user():
                return True
        except Exception:
            pass
        
        # Get account from request (set by middleware)
        account = getattr(request, 'account', None)
        
        # If no account in request, try to get from user
        if not account and hasattr(request.user, 'account'):
            try:
                account = request.user.account
            except (AttributeError, Exception):
                pass
        
        # Regular users must have account access
        if account:
            # Check if user belongs to this account
            if hasattr(request.user, 'account'):
                try:
                    user_account = request.user.account
                    return user_account == account or user_account.id == account.id
                except (AttributeError, Exception):
                    pass
        
        return False


class IsViewerOrAbove(permissions.BasePermission):
    """
    Permission class that requires viewer, editor, admin, or owner role
    For read-only operations
    Superusers and developers bypass this check.
    """
    def has_permission(self, request, view):
        if not request.user or not request.user.is_authenticated:
            return False
        
        # Bypass for superusers
        if getattr(request.user, 'is_superuser', False):
            return True
        
        # Bypass for developers
        if hasattr(request.user, 'role') and request.user.role == 'developer':
            return True
        
        # Check user role
        if hasattr(request.user, 'role'):
            role = request.user.role
            # viewer, editor, admin, owner all have access
            return role in ['viewer', 'editor', 'admin', 'owner']
        
        # If no role system, allow authenticated users
        return True


class IsEditorOrAbove(permissions.BasePermission):
    """
    Permission class that requires editor, admin, or owner role
    For content operations
    Superusers and developers bypass this check.
    """
    def has_permission(self, request, view):
        if not request.user or not request.user.is_authenticated:
            return False
        
        # Bypass for superusers
        if getattr(request.user, 'is_superuser', False):
            return True
        
        # Bypass for developers
        if hasattr(request.user, 'role') and request.user.role == 'developer':
            return True
        
        # Check user role
        if hasattr(request.user, 'role'):
            role = request.user.role
            # editor, admin, owner have access
            return role in ['editor', 'admin', 'owner']
        
        # If no role system, allow authenticated users
        return True


class IsAdminOrOwner(permissions.BasePermission):
    """
    Permission class that requires admin or owner role only
    For settings, keys, billing operations
    Superusers and developers bypass this check.
    """
    def has_permission(self, request, view):
        if not request.user or not request.user.is_authenticated:
            return False
        
        # Bypass for superusers
        if getattr(request.user, 'is_superuser', False):
            return True
        
        # Bypass for developers
        if hasattr(request.user, 'role') and request.user.role == 'developer':
            return True
        
        # Check user role
        if hasattr(request.user, 'role'):
            role = request.user.role
            # admin, owner have access
            return role in ['admin', 'owner']
        
        # If no role system, deny by default for security
        return False


class IsSystemAccountOrDeveloper(permissions.BasePermission):
    """
    Allow only system accounts (aws-admin/default-account/default) or developer role.
    Use for sensitive, globally-scoped settings like integration API keys.
    """
    def has_permission(self, request, view):
        user = getattr(request, "user", None)
        if not user or not user.is_authenticated:
            return False

        account_slug = getattr(getattr(user, "account", None), "slug", None)
        if user.role == "developer":
            return True
        if account_slug in ["aws-admin", "default-account", "default"]:
            return True
        return False


