from django.urls import reverse
from rest_framework.test import APITestCase, APIClient
from rest_framework import status
from django.contrib.auth import get_user_model
from django.utils import timezone

from helpdesk.models import Ticket

UserModel = get_user_model()

class TicketViewSetFunctionalTest(APITestCase):

    def setUp(self):
        # สร้าง Agent User
        self.agent = UserModel.objects.create_user(
            username="agent1",
            email="agent1@example.com",
            password="password123",
            is_staff=True
        )

        # สร้าง Customer User
        self.customer = UserModel.objects.create_user(
            username="customer1",
            email="customer1@example.com",
            password="password123",
            is_staff=False
        )

        # Client สำหรับ Agent
        self.client_agent = APIClient()
        self.client_agent.force_authenticate(user=self.agent)

        # Client สำหรับ Customer
        self.client_customer = APIClient()
        self.client_customer.force_authenticate(user=self.customer)

        # สร้าง Ticket ตัวอย่าง
        self.ticket = Ticket.objects.create(
            creator=self.customer,
            title="Functional Test Ticket",
            last_message_at=timezone.now()
        )

    def test_ticket_list_authenticated(self):
        """GET /tickets/ ต้อง return 200 สำหรับผู้ใช้ล็อกอิน"""
        url = reverse('helpdesk-tickets-list')  # ต้องตรงกับ router name
        response = self.client_agent.get(url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertTrue(isinstance(response.data, list))

    def test_ticket_list_unauthenticated(self):
        """GET /tickets/ ต้อง return 401 สำหรับผู้ใช้ไม่ล็อกอิน"""
        client = APIClient()  # client ไม่ล็อกอิน
        url = reverse('helpdesk-tickets-list')
        response = client.get(url)
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

    def test_resolve_ticket_by_agent(self):
        """POST /tickets/{id}/resolve/ ต้องเปลี่ยนสถานะ Ticket เป็น RESOLVED"""
        resolve_url = reverse('helpdesk-tickets-resolve', args=[self.ticket.id])

        # ACT: Agent เรียก resolve
        response = self.client_agent.post(resolve_url)

        # ASSERT
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['status'], 'RESOLVED')

        # ตรวจสอบใน DB อีกครั้ง
        self.ticket.refresh_from_db()
        self.assertEqual(self.ticket.status, 'RESOLVED')

    def test_resolve_ticket_unauthenticated_fails(self):
        """POST /tickets/{id}/resolve/ ต้อง return 401 เมื่อไม่ล็อกอิน"""
        client = APIClient()
        resolve_url = reverse('helpdesk-tickets-resolve', args=[self.ticket.id])
        response = client.post(resolve_url)
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

    def test_assign_ticket_by_agent(self):
        """POST /tickets/{id}/assign/ ต้องมอบหมาย Ticket ให้ Agent ที่ระบุ"""
        # สร้าง Agent ที่สองเพื่อมอบหมายไปหา
        agent2 = UserModel.objects.create_user(username="agent2", email="agent2@example.com", password="p", is_staff=True)
        assign_url = reverse('helpdesk-tickets-assign', args=[self.ticket.id])
        payload = {'assignee_id': agent2.id}

        # ACT: Agent1 เรียก assign
        response = self.client_agent.post(assign_url, payload, format='json')

        # ASSERT
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        # ตรวจสอบว่า assigned_to ใน Response ตรงกับ ID ของ agent2
        self.assertEqual(response.data['assigned_to']['id'], agent2.id)

        # ตรวจสอบใน DB อีกครั้ง
        self.ticket.refresh_from_db()
        self.assertEqual(self.ticket.assigned_to, agent2)

    def test_assign_ticket_to_non_existent_user_fails(self):
        """POST /tickets/{id}/assign/ ต้อง return 400 เมื่อมอบหมายให้ User ที่ไม่มีอยู่"""
        assign_url = reverse('helpdesk-tickets-assign', args=[self.ticket.id])
        # ใช้ ID ที่ไม่มีอยู่จริง (สมมติว่า ID 999999 ไม่มี)
        payload = {'assignee_id': 999999}

        response = self.client_agent.post(assign_url, payload, format='json')

        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
        # ตรวจสอบว่าข้อความ Error สื่อถึงปัญหา (ขึ้นอยู่กับ logic ใน ViewSet/Service)
        self.assertIn('not found', response.data['detail'])
