from rest_framework import status
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from django.contrib.auth import get_user_model
from django.shortcuts import get_object_or_404

from .models import Group, GroupMember
from .serializers import (
    GroupSerializer, GroupCreateSerializer,
    GroupMemberSerializer, AddMemberSerializer, ChangeRoleSerializer
)
from .permissions import GroupPermissionMixin
from posts.models import Post
from posts.serializers import PostSerializer, PostCreateSerializer

User = get_user_model()


# =============================================================================
# Group CRUD
# =============================================================================

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def list_groups(request):
    """List all groups the user is a member of."""
    user_groups = Group.objects.filter(
        members__user=request.user,
        members__is_active=True,
        is_deleted=False
    ).distinct()
    return Response(GroupSerializer(user_groups, many=True, context={'request': request}).data)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def create_group(request):
    """Create a new group. Creator becomes admin."""
    serializer = GroupCreateSerializer(data=request.data, context={'request': request})
    if serializer.is_valid():
        group = serializer.save()
        return Response(GroupSerializer(group, context={'request': request}).data, status=status.HTTP_201_CREATED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_group(request, group_id):
    """Get group details."""
    group = get_object_or_404(Group, id=group_id, is_deleted=False)
    if not GroupPermissionMixin.is_member(request.user, group):
        return Response({'error': 'Not a member'}, status=status.HTTP_403_FORBIDDEN)
    return Response(GroupSerializer(group, context={'request': request}).data)


@api_view(['PUT', 'PATCH'])
@permission_classes([IsAuthenticated])
def update_group(request, group_id):
    """Update group. Admin only."""
    group = get_object_or_404(Group, id=group_id, is_deleted=False)
    if not GroupPermissionMixin.is_admin(request.user, group):
        return Response({'error': 'Admin only'}, status=status.HTTP_403_FORBIDDEN)
    serializer = GroupSerializer(group, data=request.data, partial=True, context={'request': request})
    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['DELETE'])
@permission_classes([IsAuthenticated])
def delete_group(request, group_id):
    """Soft delete group. Admin only."""
    group = get_object_or_404(Group, id=group_id, is_deleted=False)
    if not GroupPermissionMixin.is_admin(request.user, group):
        return Response({'error': 'Admin only'}, status=status.HTTP_403_FORBIDDEN)
    group.is_deleted = True
    group.save()
    return Response({'message': 'Group deleted'})


# =============================================================================
# Member Management
# =============================================================================

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def list_members(request, group_id):
    """List group members."""
    group = get_object_or_404(Group, id=group_id, is_deleted=False)
    if not GroupPermissionMixin.is_member(request.user, group):
        return Response({'error': 'Not a member'}, status=status.HTTP_403_FORBIDDEN)
    members = GroupMember.objects.filter(group=group, is_active=True).select_related('user')
    return Response(GroupMemberSerializer(members, many=True, context={'request': request}).data)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def add_member(request, group_id):
    """Add member. Admin only."""
    group = get_object_or_404(Group, id=group_id, is_deleted=False)
    if not GroupPermissionMixin.is_admin(request.user, group):
        return Response({'error': 'Admin only'}, status=status.HTTP_403_FORBIDDEN)

    serializer = AddMemberSerializer(data=request.data)
    if not serializer.is_valid():
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    user = get_object_or_404(User, id=serializer.validated_data['user_id'])
    role = serializer.validated_data.get('role', 'MEMBER')

    existing = GroupMember.objects.filter(user=user, group=group).first()
    if existing:
        if existing.is_active:
            return Response({'error': 'Already a member'}, status=status.HTTP_400_BAD_REQUEST)
        existing.is_active = True
        existing.role = role
        existing.save()
        return Response(GroupMemberSerializer(existing, context={'request': request}).data)

    member = GroupMember.objects.create(user=user, group=group, role=role)
    return Response(GroupMemberSerializer(member, context={'request': request}).data, status=status.HTTP_201_CREATED)


@api_view(['DELETE'])
@permission_classes([IsAuthenticated])
def remove_member(request, group_id, user_id):
    """Remove member."""
    group = get_object_or_404(Group, id=group_id, is_deleted=False)
    target_user = get_object_or_404(User, id=user_id)
    if not GroupPermissionMixin.can_kick_member(request.user, group, target_user):
        return Response({'error': 'Cannot remove'}, status=status.HTTP_403_FORBIDDEN)
    member = get_object_or_404(GroupMember, user=target_user, group=group, is_active=True)
    member.is_active = False
    member.save()
    return Response({'message': 'Removed'})


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def change_role(request, group_id, user_id):
    """Change member role. Admin only."""
    group = get_object_or_404(Group, id=group_id, is_deleted=False)
    if not GroupPermissionMixin.is_admin(request.user, group):
        return Response({'error': 'Admin only'}, status=status.HTTP_403_FORBIDDEN)

    target_user = get_object_or_404(User, id=user_id)
    if target_user == request.user:
        return Response({'error': 'Cannot change own role'}, status=status.HTTP_400_BAD_REQUEST)

    serializer = ChangeRoleSerializer(data=request.data)
    if not serializer.is_valid():
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    member = get_object_or_404(GroupMember, user=target_user, group=group, is_active=True)
    member.role = serializer.validated_data['role']
    member.save()
    return Response(GroupMemberSerializer(member, context={'request': request}).data)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def leave_group(request, group_id):
    """Leave group."""
    group = get_object_or_404(Group, id=group_id, is_deleted=False)
    member = GroupMember.objects.filter(user=request.user, group=group, is_active=True).first()
    if not member:
        return Response({'error': 'Not a member'}, status=status.HTTP_400_BAD_REQUEST)
    if member.role == 'ADMIN':
        return Response({'error': 'Admin cannot leave'}, status=status.HTTP_400_BAD_REQUEST)
    member.is_active = False
    member.save()
    return Response({'message': 'Left group'})


# =============================================================================
# Group Posts (uses Post model with group ForeignKey)
# =============================================================================

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def list_group_posts(request, group_id):
    """List posts in a group."""
    group = get_object_or_404(Group, id=group_id, is_deleted=False)
    if not GroupPermissionMixin.is_member(request.user, group):
        return Response({'error': 'Not a member'}, status=status.HTTP_403_FORBIDDEN)

    # Get posts that belong to this specific group
    posts = Post.objects.filter(group=group, is_active=True).select_related('created_by', 'category')
    return Response(PostSerializer(posts, many=True, context={'request': request}).data)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def create_group_post(request, group_id):
    """Create a post in a group. Uses existing Post serializer."""
    group = get_object_or_404(Group, id=group_id, is_deleted=False)
    if not GroupPermissionMixin.is_member(request.user, group):
        return Response({'error': 'Not a member'}, status=status.HTTP_403_FORBIDDEN)

    serializer = PostCreateSerializer(data=request.data, context={'request': request})
    if serializer.is_valid():
        # Save post with group set
        post = serializer.save(group=group)
        return Response(PostSerializer(post, context={'request': request}).data, status=status.HTTP_201_CREATED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['DELETE'])
@permission_classes([IsAuthenticated])
def delete_group_post(request, group_id, post_id):
    """Delete post from group. Owner, mod, or admin can delete."""
    group = get_object_or_404(Group, id=group_id, is_deleted=False)
    post = get_object_or_404(Post, id=post_id, group=group, is_active=True)

    user_role = GroupPermissionMixin.get_user_role(request.user, group)
    if not user_role:
        return Response({'error': 'Not a member'}, status=status.HTTP_403_FORBIDDEN)

    # Admin/Mod can delete any, member can only delete own
    if user_role in ['ADMIN', 'MODERATOR'] or post.created_by == request.user:
        post.is_active = False
        post.save()
        return Response({'message': 'Deleted'})
    return Response({'error': 'Cannot delete'}, status=status.HTTP_403_FORBIDDEN)
