# atomsql/tests/test_exists.py
from atomsql.orm.models import Model
from atomsql.orm.fields import StringField, IntegerField
from atomsql.orm.query import Q


class TestModel(Model):
    name = StringField()
    age = IntegerField()


def test_exists_on_empty_table(db):
    """Should return False if no records exist."""
    db.register(TestModel)
    assert TestModel.objects().exists() is False


def test_exists_on_filtered_data(db):
    """Should return True if a match is found, False otherwise."""
    db.register(TestModel)
    TestModel(name="Alice", age=30).save()
    TestModel(name="Bob", age=25).save()

    # Match found
    assert TestModel.objects().filter(name="Alice").exists() is True
    # Match not found
    assert TestModel.objects().filter(name="Charlie").exists() is False


def test_exists_with_complex_q_logic(db):
    """Should correctly handle AND/OR logic within the EXISTS clause."""
    db.register(TestModel)
    TestModel(name="Alice", age=30).save()

    # OR condition: Alice or Age > 50 (Alice exists)
    query = Q(name="Alice") | Q(age__gt=50)
    assert TestModel.objects().filter(query).exists() is True

    # AND condition: Alice AND Age < 20 (Alice is 30, so False)
    query = Q(name="Alice") & Q(age__lt=20)
    assert TestModel.objects().filter(query).exists() is False


def test_exists_with_negation(db):
    """Should correctly handle NOT logic (exclude)."""
    db.register(TestModel)
    TestModel(name="Alice", age=30).save()

    # Exclude Alice: Table has only Alice, so exclude(Alice) is empty
    assert TestModel.objects().exclude(name="Alice").exists() is False
    # Exclude Bob: Alice is still there, so it exists
    assert TestModel.objects().exclude(name="Bob").exists() is True


def test_exists_on_chained_filters(db):
    """Should handle multiple chained .filter() calls."""
    db.register(TestModel)
    TestModel(name="Alice", age=30).save()

    # Chained filter: Name is Alice AND Age is 30
    assert TestModel.objects().filter(name="Alice").filter(age=30).exists() is True
    # Chained filter: Name is Alice AND Age is 99 (False)
    assert TestModel.objects().filter(name="Alice").filter(age=99).exists() is False
