from django.test import TestCase
from unittest.mock import MagicMock, patch
from django.contrib.auth import get_user_model
from django.utils import timezone

from chat.services.message_service import MessageService
from chat.models import Message
from helpdesk.services.ticket_service import TicketService  # Service ที่ถูกเรียก

UserModel = get_user_model()

class MessageServiceTest(TestCase):

    def setUp(self):
        # Mock Repository
        self.mock_repo = MagicMock()
        # Mock TicketService
        self.mock_ticket_service = MagicMock(spec=TicketService)
        self.mock_ticket_service.get_ticket_ref.return_value = {
            "id": 100,
            "last_message_at": timezone.now(),
            "last_message_content": "",
            "is_read": False
        }

        # Inject Mock เข้าไปใน Service
        self.service = MessageService(message_repo=self.mock_repo)
        self.service.ticket_service = self.mock_ticket_service

        # User จำลอง
        self.user = UserModel.objects.create_user(
            username='svc_tester', email='svc_tester@test.com', password='p', is_staff=True
        )

        # Message Data
        self.message_data = {
            'ticket_id': 100,
            'sender': self.user,
            'content': 'Test Message Content',
            'message_type': 'T'
        }

        # Mock create_message ให้คืนค่า Message
        self.mock_repo.create_message.return_value = Message(
            id=1, **self.message_data, timestamp=timezone.now()
        )

    @patch('chat.services.message_service.MessageService._send_realtime_update')
    def test_create_and_send_message_calls_ticket_service_contract(self, mock_send_realtime):
        # ACT
        new_message = self.service.create_and_send_message(
            ticket_id=self.message_data['ticket_id'],
            sender=self.message_data['sender'],
            content=self.message_data['content'],
            message_type=self.message_data['message_type']
        )

        # ASSERT 1 Repository ถูกเรียกเพื่อบันทึก Message
        self.mock_repo.create_message.assert_called_once_with(**self.message_data)

        # ASSERT 2 TicketService ถูกเรียกถูกต้อง
        self.mock_ticket_service.update_ticket_on_new_message.assert_called_once()
        args, kwargs = self.mock_ticket_service.update_ticket_on_new_message.call_args
        self.assertEqual(kwargs['ticket_id'], self.message_data['ticket_id'])
        self.assertIsInstance(kwargs['timestamp'], timezone.datetime)
        self.assertEqual(kwargs['sender_is_agent'], self.user.is_staff)

        # ASSERT 3 Realtime Broadcast ถูกเรียก
        mock_send_realtime.assert_called_once()