"""
Tests for model constraints and validators in the accounts app.

These tests verify that:
1. CheckConstraints raise appropriate errors
2. Validators work correctly
3. Business rules are enforced at the model level
"""

from django.db import IntegrityError
from django.test import TestCase
from django.utils import timezone

from apps.accounts.models import User


class UserConstraintTests(TestCase):
    """Tests for User model constraints."""

    def test_banned_user_without_ban_date_raises_error(self):
        """Verify banned users must have a ban_date set."""
        user = User(
            username="testuser",
            email="test@example.com",
            is_banned=True,
            ban_date=None,  # This should violate the constraint
        )

        # The constraint should be enforced at database level
        with self.assertRaises(IntegrityError):
            user.save()

    def test_banned_user_with_ban_date_saves_successfully(self):
        """Verify banned users with ban_date save successfully."""
        user = User.objects.create_user(
            username="testuser2",
            email="test2@example.com",
            password="testpass123",
            is_banned=True,
            ban_date=timezone.now(),
        )
        self.assertIsNotNone(user.pk)
        self.assertTrue(user.is_banned)
        self.assertIsNotNone(user.ban_date)

    def test_non_banned_user_without_ban_date_saves_successfully(self):
        """Verify non-banned users can be saved without ban_date."""
        user = User.objects.create_user(
            username="testuser3",
            email="test3@example.com",
            password="testpass123",
            is_banned=False,
            ban_date=None,
        )
        self.assertIsNotNone(user.pk)
        self.assertFalse(user.is_banned)

    def test_user_id_is_auto_generated(self):
        """Verify user_id is automatically generated on save."""
        user = User.objects.create_user(
            username="testuser4",
            email="test4@example.com",
            password="testpass123",
        )
        self.assertIsNotNone(user.user_id)
        self.assertTrue(len(user.user_id) >= 4)

    def test_user_id_is_unique(self):
        """Verify user_id is unique across users."""
        user1 = User.objects.create_user(
            username="testuser5",
            email="test5@example.com",
            password="testpass123",
        )
        user2 = User.objects.create_user(
            username="testuser6",
            email="test6@example.com",
            password="testpass123",
        )
        self.assertNotEqual(user1.user_id, user2.user_id)


class UserIndexTests(TestCase):
    """Tests for User model indexes."""

    def test_is_banned_field_is_indexed(self):
        """Verify is_banned field has db_index=True."""
        field = User._meta.get_field("is_banned")
        self.assertTrue(field.db_index)

    def test_role_field_is_indexed(self):
        """Verify role field has db_index=True."""
        field = User._meta.get_field("role")
        self.assertTrue(field.db_index)

    def test_composite_index_exists(self):
        """Verify composite index on (is_banned, role) exists."""
        indexes = User._meta.indexes
        index_names = [idx.name for idx in indexes]
        self.assertIn("accounts_user_banned_role_idx", index_names)
