from django.core.exceptions import ValidationError
from django.test import TestCase

from {{project_slug}}.locations.models import Address, Municipality, State


class AddressModelTest(TestCase):
    def setUp(self):
        self.state = State.objects.create(name="Test State")
        self.municipality = Municipality.objects.create(
            name="Test Municipality", state=self.state
        )

    def test_address_creation(self):
        address = Address.objects.create(
            address="123 Test St", state=self.state, municipality=self.municipality
        )
        self.assertTrue(isinstance(address, Address))
        self.assertEqual(str(address), "123 Test St")

    def test_address_fields(self):
        address = Address.objects.create(
            address="456 Sample Ave", state=self.state, municipality=self.municipality
        )
        self.assertEqual(address.address, "456 Sample Ave")
        self.assertEqual(address.state, self.state)
        self.assertEqual(address.municipality, self.municipality)

    def test_address_max_length(self):
        max_length_address = "A" * 150
        address = Address.objects.create(
            address=max_length_address, state=self.state, municipality=self.municipality
        )
        self.assertEqual(len(address.address), 150)

        with self.assertRaises(ValidationError):
            Address(
                address="A" * 151, state=self.state, municipality=self.municipality
            ).full_clean()

    def test_address_blank_field(self):
        with self.assertRaises(ValidationError):
            Address(
                address="", state=self.state, municipality=self.municipality
            ).full_clean()

    def test_address_null_state(self):
        with self.assertRaises(Address.state.RelatedObjectDoesNotExist):
            Address(address="123 Test St", municipality=self.municipality).full_clean()

    def test_address_null_municipality(self):
        with self.assertRaises(Address.municipality.RelatedObjectDoesNotExist):
            Address(
                address="123 Test St",
                state=self.state,
            ).full_clean()

    def test_address_mismatched_municipality(self):
        other_state = State.objects.create(name="Other State")
        other_municipality = Municipality.objects.create(
            name="Other Municipality", state=other_state
        )

        with self.assertRaises(ValidationError):
            Address(
                address="123 Test St", state=self.state, municipality=other_municipality
            ).full_clean()

    def test_address_update(self):
        address = Address.objects.create(
            address="123 Old St", state=self.state, municipality=self.municipality
        )
        address.address = "456 New Ave"
        address.save()
        updated_address = Address.objects.get(id=address.id)
        self.assertEqual(updated_address.address, "456 New Ave")

    def test_address_delete(self):
        address = Address.objects.create(
            address="123 Delete St", state=self.state, municipality=self.municipality
        )
        address_id = address.id
        address.delete()
        with self.assertRaises(Address.DoesNotExist):
            Address.objects.get(id=address_id)

    def test_address_unicode_characters(self):
        unicode_address = "123 Calle España, 2º"
        address = Address.objects.create(
            address=unicode_address, state=self.state, municipality=self.municipality
        )
        self.assertEqual(address.address, unicode_address)


# Add more tests as needed
