from django.contrib.auth.models import User
from django.test import TestCase
from django.urls import reverse
from rest_framework.test import APIClient

from .models import Order, Product, Table, UserRole


class PosWorkflowTests(TestCase):
    def setUp(self):
        self.table = Table.objects.create(name="Mesa 1", seats=4)
        self.product = Product.objects.create(name="Burger clásica", category="Cocina", price="12.50")
        self.waiter = User.objects.create_user(username="mesero", password="clave12345")
        UserRole.objects.filter(user=self.waiter).update(role=UserRole.Role.WAITER)
        self.kitchen = User.objects.create_user(username="cocina", password="clave12345")
        UserRole.objects.filter(user=self.kitchen).update(role=UserRole.Role.KITCHEN)

    def test_home_requires_login(self):
        response = self.client.get(reverse("home"))
        self.assertEqual(response.status_code, 302)
        self.assertIn(reverse("login"), response.url)

    def test_add_item_creates_active_order_and_marks_table_occupied(self):
        self.client.login(username="mesero", password="clave12345")
        response = self.client.post(
            reverse("table_detail", args=[self.table.pk]),
            {"product": self.product.pk, "quantity": 2, "note": "sin cebolla"},
            follow=True,
        )

        self.table.refresh_from_db()
        order = Order.objects.get(table=self.table)

        self.assertEqual(response.status_code, 200)
        self.assertEqual(order.status, Order.Status.OPEN)
        self.assertEqual(order.items.count(), 1)
        self.assertEqual(self.table.status, Table.Status.OCCUPIED)

    def test_mark_paid_frees_table(self):
        self.client.login(username="mesero", password="clave12345")
        order = Order.objects.create(table=self.table, status=Order.Status.READY)
        self.table.status = Table.Status.OCCUPIED
        self.table.save(update_fields=["status", "updated_at"])

        response = self.client.post(
            reverse("order_detail", args=[order.pk]),
            {"status": Order.Status.PAID},
            follow=True,
        )

        order.refresh_from_db()
        self.table.refresh_from_db()

        self.assertEqual(response.status_code, 200)
        self.assertEqual(order.status, Order.Status.PAID)
        self.assertEqual(self.table.status, Table.Status.FREE)

    def test_kitchen_screen_blocks_waiter_role(self):
        self.client.login(username="mesero", password="clave12345")
        response = self.client.get(reverse("kitchen_board"), follow=True)
        self.assertEqual(response.status_code, 200)
        self.assertRedirects(response, reverse("home"))

    def test_kitchen_role_can_open_kds(self):
        self.client.login(username="cocina", password="clave12345")
        response = self.client.get(reverse("kitchen_board"))
        self.assertEqual(response.status_code, 200)

    def test_jwt_login_and_me_endpoint(self):
        api_client = APIClient()
        token_response = api_client.post(
            reverse("token_obtain_pair"),
            {"username": "mesero", "password": "clave12345"},
            format="json",
        )
        self.assertEqual(token_response.status_code, 200)
        self.assertIn("access", token_response.data)

        api_client.credentials(HTTP_AUTHORIZATION=f"Bearer {token_response.data['access']}")
        me_response = api_client.get(reverse("current_user_api"))
        self.assertEqual(me_response.status_code, 200)
        self.assertEqual(me_response.data["role"], UserRole.Role.WAITER)
