from rest_framework.permissions import BasePermission, SAFE_METHODS

from apps.accounts.models import Role


STAFF_ROLES = {
    Role.SUPER_ADMIN,
    Role.ADMIN,
    Role.PROJECT_MANAGER,
    Role.FINANCE_MANAGER,
    Role.SUPPORT_STAFF,
}
ADMIN_ROLES = {Role.SUPER_ADMIN, Role.ADMIN}
FINANCE_ROLES = {Role.SUPER_ADMIN, Role.ADMIN, Role.FINANCE_MANAGER}
PROJECT_ROLES = {Role.SUPER_ADMIN, Role.ADMIN, Role.PROJECT_MANAGER}
SUPPORT_ROLES = {Role.SUPER_ADMIN, Role.ADMIN, Role.SUPPORT_STAFF}
MANAGEMENT_ROLES = {
    Role.SUPER_ADMIN,
    Role.ADMIN,
    Role.PROJECT_MANAGER,
    Role.FINANCE_MANAGER,
}


def user_role(user) -> str | None:
    if not getattr(user, "is_authenticated", False):
        return None
    return getattr(user, "role", None)


class IsAuthenticatedStaff(BasePermission):
    def has_permission(self, request, view):
        return bool(request.user and request.user.is_authenticated and request.user.role in STAFF_ROLES)


class IsAdminRole(BasePermission):
    def has_permission(self, request, view):
        return bool(request.user and request.user.is_authenticated and request.user.role in ADMIN_ROLES)


class IsFinanceRole(BasePermission):
    def has_permission(self, request, view):
        return bool(request.user and request.user.is_authenticated and request.user.role in FINANCE_ROLES)


class IsProjectRole(BasePermission):
    def has_permission(self, request, view):
        return bool(request.user and request.user.is_authenticated and request.user.role in PROJECT_ROLES)


class IsInvestorRole(BasePermission):
    def has_permission(self, request, view):
        return bool(request.user and request.user.is_authenticated and request.user.role == Role.INVESTOR)


class IsInvestorOrStaff(BasePermission):
    def has_permission(self, request, view):
        return bool(
            request.user
            and request.user.is_authenticated
            and (request.user.role == Role.INVESTOR or request.user.role in STAFF_ROLES)
        )


class ReadOnlyOrStaff(BasePermission):
    def has_permission(self, request, view):
        if request.method in SAFE_METHODS:
            return True
        return bool(request.user and request.user.is_authenticated and request.user.role in STAFF_ROLES)
