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 django.urls import reverse
from chat.models import Conversation, Message

User = get_user_model()

class ChatTestCase(TestCase):
    def setUp(self):
        self.client = APIClient()
        self.user1 = User.objects.create_user(username='u1', email='u1@e.com', password='pw')
        self.user2 = User.objects.create_user(username='u2', email='u2@e.com', password='pw')
        self.user3 = User.objects.create_user(username='u3', email='u3@e.com', password='pw')

    def test_create_conversation(self):
        """Test creating a new conversation"""
        self.client.force_authenticate(user=self.user1)
        # Fix: Serializer expects 'participant_id' and requires 'initial_message' if new
        data = {
            'participant_id': self.user2.id,
            'initial_message': 'Hello there'
        }
        response = self.client.post(reverse('conversation-list'), data)
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertTrue(Conversation.objects.filter(participants=self.user1).filter(participants=self.user2).exists())
        # Also verify message was created
        conv = Conversation.objects.filter(participants=self.user1).filter(participants=self.user2).first()
        self.assertTrue(Message.objects.filter(conversation=conv, content='Hello there').exists())

    def test_list_conversations(self):
        """Test listing conversations for a user"""
        # Create conversation
        conv = Conversation.objects.create(initiator=self.user1)
        conv.participants.add(self.user1, self.user2)
        # Ensure it has a message so it's not hidden/empty if logic requires
        Message.objects.create(conversation=conv, sender=self.user1, content="Hi")
        # Ensure visibility for user1
        from chat.models import ConversationVisibility
        ConversationVisibility.objects.create(user=self.user1, conversation=conv, is_visible=True)

        self.client.force_authenticate(user=self.user1)
        response = self.client.get(reverse('conversation-list'))
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        # Fix: Handle pagination (response.data['results'])
        results = response.data['results'] if 'results' in response.data else response.data
        self.assertEqual(len(results), 1)

    def test_send_message(self):
        """Test sending a message to a conversation"""
        conv = Conversation.objects.create()
        conv.participants.add(self.user1, self.user2)

        self.client.force_authenticate(user=self.user1)
        data = {'content': 'Hello World'}
        response = self.client.post(reverse('conversation-messages-list', args=[conv.id]), data)
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(response.data['content'], 'Hello World')
        self.assertTrue(Message.objects.filter(conversation=conv, content='Hello World').exists())

    def test_get_messages(self):
        """Test retrieving messages from a conversation"""
        conv = Conversation.objects.create()
        conv.participants.add(self.user1, self.user2)

        # Ensure visibility for user1
        from chat.models import ConversationVisibility
        ConversationVisibility.objects.create(user=self.user1, conversation=conv, is_visible=True)

        Message.objects.create(conversation=conv, sender=self.user1, content="Msg 1")
        Message.objects.create(conversation=conv, sender=self.user2, content="Msg 2")

        self.client.force_authenticate(user=self.user1)
        response = self.client.get(reverse('conversation-messages-list', args=[conv.id]))
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        # Fix: Handle pagination
        results = response.data['results'] if 'results' in response.data else response.data
        self.assertEqual(len(results), 2)
