# django_core_micha/auth/permissions.py

from django.conf import settings
from rest_framework import permissions
from rest_framework.permissions import BasePermission

from django_core_micha.auth.roles import (
    get_role_level_for_user,
    ROLE_LEVEL_0,
    ROLE_LEVEL_1,
    ROLE_LEVEL_2,
    ROLE_LEVEL_3,
    RolePolicy,
)


def _has_min_level(user, setting_name: str, default_level: int) -> bool:
    """
    Helper: Prüft, ob ein authentifizierter User superuser ist
    oder mindestens ein konfiguriertes Level erreicht.
    """
    if not user or not user.is_authenticated:
        return False
    if getattr(user, "is_superuser", False):
        return True

    min_level = getattr(settings, setting_name, default_level)
    user_level = get_role_level_for_user(user)
    return user_level >= int(min_level)


def has_invite_admin_rights(user) -> bool:
    """
    Rechte für Invite-Admin-Aktionen.

    Verwendet:
      - INVITE_MIN_ROLE_LEVEL (default: ROLE_LEVEL_2)
    oder RolePolicy, falls du es später umstellen willst.
    """
    # Variante A: reine Level-Schwelle
    return _has_min_level(
        user,
        "INVITE_MIN_ROLE_LEVEL",
        ROLE_LEVEL_2,  # default: „elevated/manager“
    )

    # Variante B (Alternative, falls du lieber Policy nutzt):
    # policy = RolePolicy()
    # return policy.is_admin_like(user)


def has_access_code_admin_rights(user) -> bool:
    """
    Rechte für Access-Code-Admin-Aktionen.

    Verwendet:
      - ACCESS_CODE_MIN_ROLE_LEVEL (default: wie INVITE_MIN_ROLE_LEVEL)
    """
    if not user or not user.is_authenticated:
        return False
    if getattr(user, "is_superuser", False):
        return True

    default_min_level = getattr(settings, "INVITE_MIN_ROLE_LEVEL", ROLE_LEVEL_2)
    min_level = getattr(settings, "ACCESS_CODE_MIN_ROLE_LEVEL", default_min_level)

    user_level = get_role_level_for_user(user)
    return user_level >= int(min_level)


class IsInviteAdminOrSuperuser(permissions.BasePermission):
    """DRF permission für invite-bezogene Admin-Aktionen."""

    def has_permission(self, request, view):
        return has_invite_admin_rights(getattr(request, "user", None))


class IsAccessCodeAdminOrSuperuser(permissions.BasePermission):
    """DRF permission für access-code-bezogene Admin-Aktionen."""

    def has_permission(self, request, view):
        return has_access_code_admin_rights(getattr(request, "user", None))


class MinRoleLevelPermission(BasePermission):
    """
    Basisklasse für Permissions, die mindestens ein bestimmtes Role-Level verlangen.
    Beispiel in einer App:

        class IsManagerOrHigher(MinRoleLevelPermission):
            min_level = ROLE_LEVEL_2
    """

    min_level = ROLE_LEVEL_0

    def has_permission(self, request, view):
        user = request.user
        if not user or not user.is_authenticated:
            return False
        return get_role_level_for_user(user) >= int(self.min_level)
