from django.test import TestCase
from django.urls import reverse
from rest_framework import status
from rest_framework.test import APITestCase
from api.property_api.state.models.state import State
from api.property_api.country.models.country import Country
from common.exceptions.exceptions import custom_exception_handler


class StateAPITestCase(APITestCase):
    def setUp(self):
        self.country = Country.objects.create(name="USA", code="US")
        self.state_1 = State.objects.create(name="California", country_id=self.country)
        self.state_2 = State.objects.create(name="LA", country_id=self.country, is_active=False)
        self.list_url = reverse("states-list-create")
        self.dropdown_url = reverse("state-dropdown")
        self.exist_url = lambda name: reverse("state-exist", kwargs={"name": name})
        self.detail_url = lambda pk: reverse("state-detail", kwargs={"pk": pk})

    def test_create_state(self):
        data = {"name": "Shah Alam", "country_id": "1"}
        response = self.client.post(self.list_url, data)
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertTrue(State.objects.filter(name="Shah Alam").exists())

    def test_list_active_states(self):
        response = self.client.get(self.list_url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(len(response.data["results"]), 1)  # only active

    def test_get_state_detail(self):
        response = self.client.get(self.detail_url(self.state_1.id))
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data["name"], self.state_1.name)

    def test_get_invalid_state_detail(self):
        response = self.client.get(self.detail_url(9999))
        self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)

    def test_update_state(self):
        data = {"name": "Californication", "country_id": self.country.id}
        response = self.client.put(self.detail_url(self.state_1.id), data)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.state_1.refresh_from_db()
        self.assertEqual(self.state_1.name, "Californication")

    def test_soft_delete_state(self):
        response = self.client.delete(self.detail_url(self.state_1.id))
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.state_1.refresh_from_db()
        self.assertFalse(self.state_1.is_active)

    def test_dropdown_returns_only_active_states(self):
        response = self.client.get(self.dropdown_url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(len(response.data), 1)

        state_data = response.data[0]
        self.assertIn("id", state_data)
        self.assertIn("name", state_data)
        self.assertNotIn("country", state_data)  # because it's not part of the serializer
        self.assertEqual(state_data["name"], "California")

    def test_dropdown_no_active_state(self):
        self.state_1.soft_delete()
        response = self.client.get(self.dropdown_url)
        self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)

    def test_state_exist_true(self):
        response = self.client.get(self.exist_url("California"))
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertTrue(response.data["isExist"])

    def test_state_exist_false(self):
        response = self.client.get(self.exist_url("nonexistent"))
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertFalse(response.data["isExist"])

    def test_state_exist_blank(self):
        response = self.client.get(self.exist_url(" "))
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)