import pytest
from django.contrib.auth import get_user_model
from apps.core.models import Tag, Attachment, Comment, Notification, AuditLog


@pytest.fixture
def user(db):
    User = get_user_model()
    return User.objects.create_user(
        email="test@example.com",
        username="testuser",
        password="testpass123"
    )


@pytest.fixture
def tag(db):
    return Tag.objects.create(name="Test Tag", color="#FF0000")


@pytest.mark.django_db
class TestUserModel:
    def test_create_user_with_email(self, db):
        User = get_user_model()
        user = User.objects.create_user(
            email="user@example.com",
            username="user1",
            password="pass123"
        )
        assert user.email == "user@example.com"
        assert user.USERNAME_FIELD == "email"

    def test_auto_username_generated(self, db):
        User = get_user_model()
        user = User.objects.create_user(
            email="autouser@example.com",
            password="pass123"
        )
        assert user.username is not None
        assert len(user.username) == 7

    def test_username_unique(self, db):
        User = get_user_model()
        user1 = User.objects.create_user(email="user1@example.com", password="pass123")
        user2 = User.objects.create_user(email="user2@example.com", password="pass123")
        assert user1.username != user2.username

    def test_user_str(self, user):
        assert str(user) == "test@example.com"


@pytest.mark.django_db
class TestTagModel:
    def test_create_tag(self, db):
        tag = Tag.objects.create(name="Important", color="#00FF00")
        assert tag.name == "Important"
        assert tag.slug == "important"

    def test_tag_slug_auto_generated(self, tag):
        assert tag.slug == "test-tag"

    def test_tag_unique_name(self, tag, db):
        with pytest.raises(Exception):
            Tag.objects.create(name="Test Tag")

    def test_tag_str(self, tag):
        assert str(tag) == "Test Tag"


@pytest.mark.django_db
class TestNotificationModel:
    def test_create_notification(self, user):
        notification = Notification.objects.create(
            user=user,
            title="Test Notification",
            message="This is a test",
            link="/test/"
        )
        assert notification.title == "Test Notification"
        assert notification.is_read is False

    def test_mark_as_read(self, user):
        notification = Notification.objects.create(
            user=user,
            title="Test",
            message="Test message"
        )
        notification.is_read = True
        notification.save()
        notification.refresh_from_db()
        assert notification.is_read is True


@pytest.mark.django_db
class TestCommentModel:
    def test_create_comment(self, user):
        comment = Comment.objects.create(
            author=user,
            content="Test comment content"
        )
        assert comment.content == "Test comment content"

    def test_comment_ordering(self, user):
        comment1 = Comment.objects.create(author=user, content="First")
        comment2 = Comment.objects.create(author=user, content="Second")
        comments = list(Comment.objects.all())
        assert comments[0].id == comment1.id
        assert comments[1].id == comment2.id


@pytest.mark.django_db
class TestAuditLogModel:
    def test_create_audit_log(self, user):
        from uuid import uuid4
        audit_log = AuditLog.objects.create(
            user=user,
            action="create",
            model_name="TestModel",
            object_id=uuid4(),
            changes={"field": "value"}
        )
        assert audit_log.action == "create"
        assert audit_log.model_name == "TestModel"