"""
Group Permissions Module

Role Capabilities (as per the implementation plan):

ADMIN:
- Delete group (soft delete)
- Add / remove moderators
- Remove members
- Approve join requests
- Manage group settings
- Full post & comment control

MODERATOR:
- Remove posts
- Remove comments
- Kick members
- View member list
- Cannot modify group structure

MEMBER:
- Create posts
- Edit / delete own posts
- Comment & react
- Leave group
"""

from rest_framework import permissions
from .models import Group, GroupMember


class IsGroupMember(permissions.BasePermission):
    """
    Check if user is a member of the group.
    """
    def has_object_permission(self, request, view, obj):
        if isinstance(obj, Group):
            group = obj
        else:
            group = getattr(obj, 'group', None)

        if not group:
            return False

        return GroupMember.objects.filter(
            user=request.user,
            group=group,
            is_active=True
        ).exists()


class IsGroupAdmin(permissions.BasePermission):
    """
    Check if user is an admin of the group.
    Admins have full control over the group.
    """
    def has_object_permission(self, request, view, obj):
        if isinstance(obj, Group):
            group = obj
        else:
            group = getattr(obj, 'group', None)

        if not group:
            return False

        return GroupMember.objects.filter(
            user=request.user,
            group=group,
            role='ADMIN',
            is_active=True
        ).exists()


class IsGroupModerator(permissions.BasePermission):
    """
    Check if user is a moderator or admin of the group.
    """
    def has_object_permission(self, request, view, obj):
        if isinstance(obj, Group):
            group = obj
        else:
            group = getattr(obj, 'group', None)

        if not group:
            return False

        return GroupMember.objects.filter(
            user=request.user,
            group=group,
            role__in=['ADMIN', 'MODERATOR'],
            is_active=True
        ).exists()


class GroupPermissionMixin:
    """
    Mixin providing helper methods for group permission checks.
    Use in views or services.
    """

    @staticmethod
    def get_user_role(user, group):
        """Get user's role in a group, or None if not a member."""
        try:
            member = GroupMember.objects.get(
                user=user,
                group=group,
                is_active=True
            )
            return member.role
        except GroupMember.DoesNotExist:
            return None

    @staticmethod
    def is_admin(user, group):
        """Check if user is admin of the group."""
        return GroupMember.objects.filter(
            user=user,
            group=group,
            role='ADMIN',
            is_active=True
        ).exists()

    @staticmethod
    def is_moderator_or_above(user, group):
        """Check if user is moderator or admin."""
        return GroupMember.objects.filter(
            user=user,
            group=group,
            role__in=['ADMIN', 'MODERATOR'],
            is_active=True
        ).exists()

    @staticmethod
    def is_member(user, group):
        """Check if user is any kind of member."""
        return GroupMember.objects.filter(
            user=user,
            group=group,
            is_active=True
        ).exists()

    @staticmethod
    def can_manage_members(user, group):
        """Check if user can add/remove members (admin only)."""
        return GroupPermissionMixin.is_admin(user, group)

    @staticmethod
    def can_manage_moderators(user, group):
        """Check if user can add/remove moderators (admin only)."""
        return GroupPermissionMixin.is_admin(user, group)

    @staticmethod
    def can_delete_group(user, group):
        """Check if user can delete the group (admin only)."""
        return GroupPermissionMixin.is_admin(user, group)

    @staticmethod
    def can_kick_member(user, group, target_user):
        """
        Check if user can kick target_user.
        - Admin can kick anyone except themselves
        - Moderator can kick members only (not admins or other mods)
        """
        if user == target_user:
            return False  # Can't kick yourself

        user_role = GroupPermissionMixin.get_user_role(user, group)
        target_role = GroupPermissionMixin.get_user_role(target_user, group)

        if not user_role or not target_role:
            return False

        if user_role == 'ADMIN':
            return True  # Admin can kick anyone

        if user_role == 'MODERATOR' and target_role == 'MEMBER':
            return True  # Mod can kick members only

        return False

    @staticmethod
    def can_delete_post(user, group, post):
        """
        Check if user can delete a post.
        - Admin & Moderator can delete any post
        - Member can delete own posts only
        """
        user_role = GroupPermissionMixin.get_user_role(user, group)

        if not user_role:
            return False

        if user_role in ['ADMIN', 'MODERATOR']:
            return True

        # Member can delete own posts
        return post.created_by == user

    @staticmethod
    def can_delete_comment(user, group, comment):
        """
        Check if user can delete a comment.
        - Admin & Moderator can delete any comment
        - Member can delete own comments only
        """
        user_role = GroupPermissionMixin.get_user_role(user, group)

        if not user_role:
            return False

        if user_role in ['ADMIN', 'MODERATOR']:
            return True

        # Member can delete own comments
        return comment.author == user
