from django.test import TestCase
from django.contrib.auth import get_user_model
from rest_framework.test import APIClient
from rest_framework import status
from posts.models import Post
from chat.models import Conversation, Message
from chat.serializers import MessageSerializer

User = get_user_model()

class SharingRestrictionsTests(TestCase):
    def setUp(self):
        self.client = APIClient()
        self.user1 = User.objects.create_user(username='user1', email='user1@example.com', password='password')
        self.user2 = User.objects.create_user(username='user2', email='user2@example.com', password='password')

        # Create a post
        self.post = Post.objects.create(created_by=self.user1, content="Test Post", audience='PUBLIC')

        # Create a conversation
        self.conversation = Conversation.objects.create(initiator=self.user1)
        self.conversation.participants.add(self.user1, self.user2)

        # Share the post
        self.message = Message.objects.create(
            conversation=self.conversation,
            sender=self.user1,
            message_type='post',
            shared_post=self.post
        )

    def test_shared_post_visibility_public(self):
        """Test that a public post is visible when shared."""
        serializer = MessageSerializer(self.message, context={'request': type('obj', (object,), {'user': self.user2})})
        data = serializer.data
        self.assertTrue(data['shared_post']['is_available'])
        self.assertEqual(data['shared_post']['id'], self.post.id)

    def test_shared_post_visibility_deleted(self):
        """Test that a deleted post shows as unavailable."""
        self.post.is_active = False
        self.post.save()

        serializer = MessageSerializer(self.message, context={'request': type('obj', (object,), {'user': self.user2})})
        data = serializer.data
        self.assertFalse(data['shared_post']['is_available'])
        self.assertNotIn('content', data['shared_post'])

    def test_shared_post_visibility_restricted(self):
        """Test that a followers-only post shows as unavailable to non-followers."""
        self.post.audience = 'FOLLOWERS'
        self.post.save()

        # user2 is not following user1
        serializer = MessageSerializer(self.message, context={'request': type('obj', (object,), {'user': self.user2})})
        data = serializer.data
        self.assertFalse(data['shared_post']['is_available'])

    def test_shared_post_visibility_authorized(self):
        """Test that a followers-only post shows as available to followers."""
        self.post.audience = 'FOLLOWERS'
        self.post.save()

        # Make user2 follow user1
        from follows.models import FollowUser
        FollowUser.objects.create(follower=self.user2, followed=self.user1)

        serializer = MessageSerializer(self.message, context={'request': type('obj', (object,), {'user': self.user2})})
        data = serializer.data
        self.assertTrue(data['shared_post']['is_available'])

    def test_share_private_post_fails(self):
        """Test that attempting to share a private (ONLY_ME) post fails validation."""
        self.post.audience = 'ONLY_ME'
        self.post.save()
        
        from chat.serializers import MessageCreateSerializer
        serializer = MessageCreateSerializer(data={
            'shared_post_id': self.post.id,
            'content': 'Check this out'
        })
        self.assertFalse(serializer.is_valid())
        self.assertIn('shared_post_id', serializer.errors)
        self.assertEqual(serializer.errors['shared_post_id'][0], "Ce post est privé et ne peut pas être partagé.")
