from rest_framework.test import APITestCase
from rest_framework import status
from django.contrib.auth import get_user_model
from .models import Device
from django.contrib.auth.models import Permission

User = get_user_model()


class DeviceAPITestCase(APITestCase):
    def setUp(self):
        self.user = User.objects.create_user(username="testuser", password="password")
        self.user.user_permissions.add(
            Permission.objects.get(codename="add_device"),
            Permission.objects.get(codename="delete_device"),
            Permission.objects.get(codename="view_device"),
            Permission.objects.get(codename="change_device"),
        )
        self.superuser = User.objects.create_superuser(
            username="admin", password="password", email="admin@example.com"
        )
        self.device = Device.objects.create(
            name="Test Device", mac="00:1A:2B:3C:4D:5E", user=self.user
        )
        self.client.login(
            username="testuser", password="password", email="admin@example.com"
        )
        self.token = self.client.post(
            "/api/auth/login/",
            {"username": "admin@example.com", "password": "password"},
        ).data["token"]

    def test_list_devices(self):
        self.client.credentials(HTTP_AUTHORIZATION=f"Token {self.token}")
        response = self.client.get("/api/devices/")
        self.assertEqual(response.status_code, status.HTTP_200_OK)

    def test_create_device(self):
        self.client.credentials(HTTP_AUTHORIZATION=f"Token {self.token}")
        data = {"name": "New Device", "mac": "11:22:33:44:55:66"}
        response = self.client.post("/api/devices/", data)
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)

    def test_create_device_invalid_mac(self):
        self.client.credentials(HTTP_AUTHORIZATION=f"Token {self.token}")
        data = {"name": "Invalid Device", "mac": "invalid-mac"}
        response = self.client.post("/api/devices/", data)
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
        self.assertIn("Invalid mac address.", response.data["message"])

    def test_update_device(self):
        self.client.credentials(HTTP_AUTHORIZATION=f"Token {self.token}")
        data = {"name": "Updated Device"}
        response = self.client.patch(f"/api/devices/{self.device.pk}/update/", data)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.device.refresh_from_db()
        self.assertEqual(self.device.name, "Updated Device")

    def test_block_device(self):
        self.client.credentials(HTTP_AUTHORIZATION=f"Token {self.token}")
        data = {
            "blocked": True,  # also use Python boolean here, not a string
            "reason_for_blocking": "hello",
            "blocked_by": "ADMIN",
        }
        response = self.client.put(
            f"/api/devices/{self.device.pk}/block/",
            data,
            format="json",  # ✅ this is crucial!
        )
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.device.refresh_from_db()
        self.assertTrue(self.device.blocked)

    def test_delete_device(self):
        self.client.credentials(HTTP_AUTHORIZATION=f"Token {self.token}")
        response = self.client.delete(f"/api/devices/{self.device.pk}/delete/")
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertFalse(Device.objects.filter(pk=self.device.pk).exists())