# users/permissions.py
from rest_framework import permissions


class IsAuthorizedTenant(permissions.BasePermission):

    def has_permission(self, request, view):
        """
        General permission check (before accessing view).
        Allows:
        - Superusers: full access
        - Citizens: can access TenantViewSet (list/detail)
        - Others: rely on object-level permissions for specific objects
        """
        user = request.user
        if not user or not user.is_authenticated:
            return False

        # Superuser can do anything
        if user.is_superuser:
            return True

        # Citizen role: allow viewing tenant lists
        has_citizen_role = user.user_roles_set.filter(
            role__role_name="Citizen"
        ).exists()
        if has_citizen_role:
            if view.__class__.__name__ == "TenantViewSet":
                return True
            return True  # allow viewset to handle filtering for other views

        # Other users: allow view, object-level permission will restrict
        return True

    def has_object_permission(self, request, view, obj):
        """
        Object-level permission check.
        Allows:
        - Superusers: full access
        - Citizens: cannot modify specific tenant objects
        - Regular officers: can access their tenant and descendant tenants
        """
        user = request.user

        # Superusers can do anything
        if user.is_superuser:
            return True

        # Citizen role cannot access individual tenant objects
        has_citizen_role = user.user_roles_set.filter(
            role__role_name="Citizen"
        ).exists()
        if has_citizen_role:
            return False

        # Regular officers: access if tenant is theirs or a descendant
        user_tenants = user.user_roles_set.values_list("tenant_id", flat=True)
        if hasattr(obj, "tenant_id"):
            # Allow if the tenant is the user's tenant or a descendant
            return obj.tenant_id in user_tenants

        # Default deny
        return False


class IsAdminOrITOfficer(permissions.BasePermission):
    """
    Custom permission to allow a user to invite a new officer based on their role
    and tenant.
    - Super Admins can invite anyone.
    - Ministry IT Officers can only invite users to their own tenant.
    """

    def has_permission(self, request, view):
        user = request.user
        if not user.is_authenticated:
            return False

        # If the user is a Super Admin, they have permission
        if user.is_superuser:
            return True

        # Check if the user is a Ministry IT Officer
        is_it_officer = user.user_roles_set.filter(
            role__role_name="Ministry IT Officer"
        ).exists()

        if is_it_officer:
            # Get the tenant the IT Officer belongs to
            it_officer_tenant_id = (
                user.user_roles_set.filter(role__role_name="Ministry IT Officer")
                .first()
                .tenant_id
            )

            # Get the tenant ID from the request data for the new user
            new_user_tenant_id = request.data.get("tenant_id")

            # The IT officer can only invite users to their own ministry
            return str(it_officer_tenant_id) == str(new_user_tenant_id)

        return False
