import pytest
import sys
from pathlib import Path

# Add parent of db_core to path
parent_dir = Path(__file__).parent.parent.parent
if str(parent_dir) not in sys.path:
    sys.path.insert(0, str(parent_dir))

from db_core.clients.postgresql import PostgresClient

pytestmark = pytest.mark.pg


@pytest.mark.asyncio
async def test_select_all(db_client: PostgresClient):
    """Test selecting all records"""
    result = await db_client.table("users").get()
    assert result.count() == 4
    assert len(result.all()) == 4


@pytest.mark.asyncio
async def test_where_basic(db_client: PostgresClient):
    """Test basic where clause"""
    result = await db_client.table("users").where("name", "Alice Smith").get()
    assert result.count() == 1
    assert result.first()["email"] == "alice@example.com"


@pytest.mark.asyncio
async def test_where_operator(db_client: PostgresClient):
    """Test where with operator"""
    result = await db_client.table("users").where("age", ">", 28).get()
    assert result.count() == 2


@pytest.mark.asyncio
async def test_where_gte(db_client: PostgresClient):
    """Test where_gte helper"""
    result = await db_client.table("users").where_gte("age", 30).get()
    assert result.count() == 2


@pytest.mark.asyncio
async def test_where_gt(db_client: PostgresClient):
    """Test where_gt helper"""
    result = await db_client.table("users").where_gt("age", 30).get()
    assert result.count() == 1


@pytest.mark.asyncio
async def test_where_lte(db_client: PostgresClient):
    """Test where_lte helper"""
    result = await db_client.table("users").where_lte("age", 28).get()
    assert result.count() == 2


@pytest.mark.asyncio
async def test_where_lt(db_client: PostgresClient):
    """Test where_lt helper"""
    result = await db_client.table("users").where_lt("age", 30).get()
    assert result.count() == 2


@pytest.mark.asyncio
async def test_where_not_eq(db_client: PostgresClient):
    """Test where_not_eq helper"""
    result = await db_client.table("users").where_not_eq("age", 30).get()
    assert result.count() == 3


@pytest.mark.asyncio
async def test_where_in(db_client: PostgresClient):
    """Test where_in clause"""
    result = await db_client.table("users").where_in("age", [25, 30]).get()
    assert result.count() == 2


@pytest.mark.asyncio
async def test_or_where(db_client: PostgresClient):
    """Test OR conditions"""
    result = await (
        db_client.table("users")
        .where("age", 25)
        .or_where("age", 30)
        .get()
    )
    assert result.count() == 2


@pytest.mark.asyncio
async def test_complex_or_where(db_client: PostgresClient):
    """Test complex OR conditions with AND"""
    result = await (
        db_client.table("posts")
        .where("published", True)
        .where_group(lambda q: q.where_gt("views", 60).or_where("views", 50))
        .get()
    )
    assert result.count() >= 2


@pytest.mark.asyncio
async def test_select_specific_fields(db_client: PostgresClient):
    """Test selecting specific fields"""
    result = await db_client.table("users").select("name", "email").get()
    first = result.first()
    assert "name" in first
    assert "email" in first
    assert result.count() == 4


@pytest.mark.asyncio
async def test_order_by(db_client: PostgresClient):
    """Test ordering results"""
    result = await db_client.table("users").order_by("age").get()
    ages = [row["age"] for row in result.all()]
    assert ages == sorted(ages)


@pytest.mark.asyncio
async def test_order_by_desc(db_client: PostgresClient):
    """Test descending order"""
    result = await db_client.table("users").order_by("-age").get()
    ages = [row["age"] for row in result.all()]
    assert ages == sorted(ages, reverse=True)


@pytest.mark.asyncio
async def test_limit(db_client: PostgresClient):
    """Test limit clause"""
    result = await db_client.table("users").limit(2).get()
    assert result.count() == 2


@pytest.mark.asyncio
async def test_offset(db_client: PostgresClient):
    """Test offset clause"""
    result = await db_client.table("users").order_by("id").offset(2).get()
    assert result.count() == 2


@pytest.mark.asyncio
async def test_limit_offset_combined(db_client: PostgresClient):
    """Test limit and offset together"""
    result = await db_client.table("users").order_by("id").limit(2).offset(1).get()
    assert result.count() == 2


@pytest.mark.asyncio
async def test_first(db_client: PostgresClient):
    """Test first() method"""
    user = await db_client.table("users").where("name", "Alice Smith").first()
    assert user is not None
    assert user["email"] == "alice@example.com"


@pytest.mark.asyncio
async def test_all(db_client: PostgresClient):
    """Test all() method"""
    users = await db_client.table("users").all()
    assert len(users) == 4
    assert isinstance(users, list)


@pytest.mark.asyncio
async def test_one(db_client: PostgresClient):
    """Test one() method"""
    result = await db_client.table("users").where("email", "alice@example.com").get()
    user = result.one()
    assert user["name"] == "Alice Smith"


@pytest.mark.asyncio
async def test_one_raises_on_multiple(db_client: PostgresClient):
    """Test that one() raises when multiple rows returned"""
    with pytest.raises(ValueError, match="Expected exactly one row"):
        result = await db_client.table("users").get()
        result.one()


@pytest.mark.asyncio
async def test_one_raises_on_zero(db_client: PostgresClient):
    """Test that one() raises when no rows returned"""
    with pytest.raises(ValueError, match="Expected exactly one row"):
        result = await db_client.table("users").where("id", -1).get()
        result.one()


@pytest.mark.asyncio
async def test_where_like(db_client: PostgresClient):
    """Test LIKE operator"""
    result = await db_client.table("users").where_like("name", "%Brown%").get()
    assert result.count() == 1
    assert result.first()["name"] == "Charlie Brown"


@pytest.mark.asyncio
async def test_where_ilike(db_client: PostgresClient):
    """Test ILIKE operator (case insensitive)"""
    result = await db_client.table("users").where_ilike("name", "%BROWN%").get()
    assert result.count() == 1
    assert result.first()["name"] == "Charlie Brown"


@pytest.mark.asyncio
async def test_chaining(db_client: PostgresClient):
    """Test method chaining"""
    result = await (
        db_client.table("posts")
        .where("published", True)
        .where_gt("views", 50)
        .order_by("-views")
        .limit(2)
        .get()
    )
    assert result.count() <= 2
    rows = result.all()
    if len(rows) > 1:
        assert rows[0]["views"] >= rows[1]["views"]


@pytest.mark.asyncio
async def test_where_group_and(db_client: PostgresClient):
    """Test grouped AND conditions"""
    result = await (
        db_client.table("users")
        .where("age", ">", 25)
        .where_group(lambda q: q.where("name", "Alice Smith").or_where("name", "Charlie Brown"))
        .get()
    )
    assert result.count() == 2
    names = [row["name"] for row in result.all()]
    assert "Alice Smith" in names
    assert "Charlie Brown" in names


@pytest.mark.asyncio
async def test_or_where_group_combination(db_client: PostgresClient):
    """Test OR grouped conditions combined with top-level WHERE"""
    result = await (
        db_client.table("posts")
        .where("published", True)
        .or_where_group(lambda q: q.where("views", 0).where("title", "Draft Post"))
        .get()
    )
    assert result.count() == 4
    titles = {row["title"] for row in result.all()}
    assert "Draft Post" in titles
    assert "First Post" in titles
    assert "Second Post" in titles
    assert "Bob's Post" in titles


@pytest.mark.asyncio
async def test_complex_where_group_combination(db_client: PostgresClient):
    """Test nested groups combined with OR conditions"""
    result = await (
        db_client.table("posts")
        .where_group(lambda q:
            q.where("published", True)
             .where_group(lambda q2: q2.where_gte("views", 100).or_where("title", "Bob's Post"))
        )
        .or_where("title", "Draft Post")
        .get()
    )
    assert result.count() == 3
    titles = {row["title"] for row in result.all()}
    assert titles == {"First Post", "Bob's Post", "Draft Post"}


@pytest.mark.asyncio
async def test_where_group_nested(db_client: PostgresClient):
    """Test nested groups"""
    result = await (
        db_client.table("posts")
        .where_group(lambda q: 
            q.where("published", True)
             .where_group(lambda q2: q2.where_gte("views", 50).or_where("views", 100))
        )
        .get()
    )
    assert result.count() >= 2


# ---------------------------------------------------------------------------
# New builder helper methods — count, exists, one
# ---------------------------------------------------------------------------

@pytest.mark.asyncio
async def test_builder_count(db_client: PostgresClient):
    """Test count() on the builder"""
    n = await db_client.table("users").count()
    assert n == 4

    n = await db_client.table("users").where("age", ">", 28).count()
    assert n == 2


@pytest.mark.asyncio
async def test_builder_exists(db_client: PostgresClient):
    """Test exists() on the builder"""
    yes = await db_client.table("users").where("email", "alice@example.com").exists()
    assert yes is True

    no = await db_client.table("users").where("email", "nobody@example.com").exists()
    assert no is False


@pytest.mark.asyncio
async def test_builder_one(db_client: PostgresClient):
    """Test one() on the builder"""
    user = await db_client.table("users").where("email", "alice@example.com").one()
    assert user["name"] == "Alice Smith"


@pytest.mark.asyncio
async def test_builder_one_raises_on_multiple(db_client: PostgresClient):
    """Test one() raises ValueError when multiple rows match"""
    with pytest.raises(ValueError, match="Expected exactly one row"):
        await db_client.table("users").one()


@pytest.mark.asyncio
async def test_builder_one_raises_on_zero(db_client: PostgresClient):
    """Test one() raises ValueError when no rows match"""
    with pytest.raises(ValueError, match="Expected exactly one row"):
        await db_client.table("users").where("id", -1).one()


# ---------------------------------------------------------------------------
# Builder mutation helpers — create, create_many, save, update, delete, remove
# ---------------------------------------------------------------------------

@pytest.mark.asyncio
async def test_builder_create(db_client: PostgresClient):
    """Test create() on the builder"""
    user = await db_client.table("users").create(
        {"name": "Eve Test", "email": "eve@example.com", "age": 22},
        returning=["id", "name", "email", "age"],
    )
    assert user is not None
    assert user["name"] == "Eve Test"
    assert user["email"] == "eve@example.com"
    assert "id" in user

    # Verify it's actually in the DB
    found = await db_client.table("users").where("email", "eve@example.com").first()
    assert found is not None
    assert found["name"] == "Eve Test"

    # Cleanup
    await db_client.delete("users", {"email": "eve@example.com"})


@pytest.mark.asyncio
async def test_builder_create_many(db_client: PostgresClient):
    """Test create_many() on the builder"""
    users = await db_client.table("users").create_many(
        [
            {"name": "Frank Test", "email": "frank@example.com", "age": 27},
            {"name": "Grace Test", "email": "grace@example.com", "age": 32},
        ],
        returning=["id", "name", "email", "age"],
    )
    assert len(users) == 2
    names = {u["name"] for u in users}
    assert names == {"Frank Test", "Grace Test"}

    # Verify they're in the DB
    found = await db_client.table("users").where_in(
        "email", ["frank@example.com", "grace@example.com"]
    ).all()
    assert len(found) == 2

    # Cleanup
    await db_client.delete("users", {"email": "frank@example.com"})
    await db_client.delete("users", {"email": "grace@example.com"})


@pytest.mark.asyncio
async def test_builder_save_insert(db_client: PostgresClient):
    """Test save() inserts when no id_field is present"""
    user = await db_client.table("users").save(
        {"name": "Henry Test", "email": "henry@example.com", "age": 40},
        returning=["id", "name", "email", "age"],
    )
    assert user is not None
    assert user["name"] == "Henry Test"

    # Cleanup
    await db_client.delete("users", {"email": "henry@example.com"})


@pytest.mark.asyncio
async def test_builder_save_update(db_client: PostgresClient):
    """Test save() updates when id_field is present"""
    # First, create a user
    created = await db_client.table("users").create(
        {"name": "Iris Test", "email": "iris@example.com", "age": 29},
        returning=["id", "name", "email", "age"],
    )
    record_id = created["id"]

    # Now save with the id — should update
    updated = await db_client.table("users").save(
        {"id": record_id, "name": "Iris Updated", "email": "iris@example.com", "age": 30},
        returning=["id", "name", "email", "age"],
    )
    assert updated is not None
    assert updated["name"] == "Iris Updated"
    assert updated["age"] == 30

    # Cleanup
    await db_client.delete("users", {"email": "iris@example.com"})


@pytest.mark.asyncio
async def test_builder_update(db_client: PostgresClient):
    """Test update() on the builder with where conditions"""
    # Create a test user
    await db_client.table("users").create(
        {"name": "Jack Test", "email": "jack@example.com", "age": 35}
    )

    # Update via builder
    updated_count = await (
        db_client.table("users")
        .where("email", "jack@example.com")
        .update(name="Jack Updated", age=36)
    )
    assert updated_count == 1

    # Verify
    user = await db_client.table("users").where("email", "jack@example.com").first()
    assert user is not None
    assert user["name"] == "Jack Updated"
    assert user["age"] == 36

    # Cleanup
    await db_client.delete("users", {"email": "jack@example.com"})


@pytest.mark.asyncio
async def test_builder_delete(db_client: PostgresClient):
    """Test delete() on the builder with where conditions"""
    # Create a test user to delete
    await db_client.table("users").create(
        {"name": "Kate Test", "email": "kate@example.com", "age": 24}
    )

    # Delete via builder
    deleted_count = await (
        db_client.table("users")
        .where("email", "kate@example.com")
        .delete()
    )
    assert deleted_count == 1

    # Verify gone
    user = await db_client.table("users").where("email", "kate@example.com").first()
    assert user is None


@pytest.mark.asyncio
async def test_builder_remove(db_client: PostgresClient):
    """Test remove() as alias for delete()"""
    # Create a test user
    await db_client.table("users").create(
        {"name": "Leo Test", "email": "leo@example.com", "age": 26}
    )

    # Remove via builder
    removed_count = await (
        db_client.table("users")
        .where("email", "leo@example.com")
        .remove()
    )
    assert removed_count == 1

    # Verify gone
    user = await db_client.table("users").where("email", "leo@example.com").first()
    assert user is None


@pytest.mark.asyncio
async def test_builder_update_with_limit(db_client: PostgresClient):
    """Test update() respects limit from the builder query"""
    # Create two test users with same status-like pattern
    await db_client.table("users").create_many([
        {"name": "Mia Test", "email": "mia@example.com", "age": 20},
        {"name": "Nick Test", "email": "nick@example.com", "age": 21},
    ])

    # Update only one (limit 1)
    count = await (
        db_client.table("users")
        .where_in("email", ["mia@example.com", "nick@example.com"])
        .limit(1)
        .update(age=50)
    )
    assert count == 1

    # Only one should be updated
    users = await db_client.table("users").where_in(
        "email", ["mia@example.com", "nick@example.com"]
    ).all()
    ages = {u["age"] for u in users}
    assert 50 in ages  # at least one updated

    # Cleanup
    await db_client.delete("users", {"email": "mia@example.com"})
    await db_client.delete("users", {"email": "nick@example.com"})


@pytest.mark.asyncio
async def test_builder_delete_with_limit(db_client: PostgresClient):
    """Test delete() respects limit from the builder query"""
    # Create two test users
    await db_client.table("users").create_many([
        {"name": "Olive Test", "email": "olive@example.com", "age": 23},
        {"name": "Pat Test", "email": "pat@example.com", "age": 23},
    ])

    # Delete only one (limit 1)
    count = await (
        db_client.table("users")
        .where_in("email", ["olive@example.com", "pat@example.com"])
        .limit(1)
        .delete()
    )
    assert count == 1

    # Only one should remain
    remaining = await db_client.table("users").where_in(
        "email", ["olive@example.com", "pat@example.com"]
    ).all()
    assert len(remaining) == 1

    # Cleanup the survivor
    await db_client.delete("users", {"email": remaining[0]["email"]})


# ---------------------------------------------------------------------------
# Edge‑case tests — count, exists, one
# ---------------------------------------------------------------------------


@pytest.mark.asyncio
async def test_builder_count_zero(db_client: PostgresClient):
    """Test count() returns 0 when nothing matches"""
    n = await db_client.table("users").where("email", "nobody@example.com").count()
    assert n == 0


@pytest.mark.asyncio
async def test_builder_count_with_or(db_client: PostgresClient):
    """Test count() with OR condition"""
    n = await (
        db_client.table("users")
        .where("name", "Alice Smith")
        .or_where("name", "Bob Jones")
        .count()
    )
    assert n == 2


@pytest.mark.asyncio
async def test_builder_count_with_like(db_client: PostgresClient):
    """Test count() with LIKE pattern"""
    n = await db_client.table("users").where_like("name", "%Smith%").count()
    assert n == 1


@pytest.mark.asyncio
async def test_builder_exists_no_match(db_client: PostgresClient):
    """Test exists() returns False for non‑matching conditions"""
    no = await db_client.table("posts").where("published", False).where_gt("views", 50).exists()
    assert no is False


@pytest.mark.asyncio
async def test_builder_exists_complex(db_client: PostgresClient):
    """Test exists() with chained AND + OR"""
    yes = await (
        db_client.table("posts")
        .where("published", True)
        .where_group(lambda q: q.where_gt("views", 70).or_where("title", "Bob's Post"))
        .exists()
    )
    assert yes is True


@pytest.mark.asyncio
async def test_builder_one_on_empty_table(db_client: PostgresClient):
    """Test one() raises ValueError when table is effectively empty for the query"""
    with pytest.raises(ValueError, match="Expected exactly one row"):
        await db_client.table("users").where("id", 99999).one()


# ---------------------------------------------------------------------------
# Edge‑case tests — create, create_many, save
# ---------------------------------------------------------------------------


@pytest.mark.asyncio
async def test_builder_create_without_returning(db_client: PostgresClient):
    """Test create() without returning clause returns None"""
    user = await db_client.table("users").create(
        {"name": "Quinn Test", "email": "quinn@example.com", "age": 31}
    )
    assert user is None

    # Still verify it was inserted
    found = await db_client.table("users").where("email", "quinn@example.com").first()
    assert found is not None
    assert found["name"] == "Quinn Test"

    # Cleanup
    await db_client.delete("users", {"email": "quinn@example.com"})


@pytest.mark.asyncio
async def test_builder_create_duplicate_email_raises(db_client: PostgresClient):
    """Test create() with a duplicate unique field raises an error"""
    with pytest.raises(Exception):
        await db_client.table("users").create(
            {"name": "Duplicate", "email": "alice@example.com", "age": 40}
        )


@pytest.mark.asyncio
async def test_builder_create_many_empty(db_client: PostgresClient):
    """Test create_many() with an empty list returns an empty list"""
    result = await db_client.table("users").create_many([])
    assert result == []


@pytest.mark.asyncio
async def test_builder_create_many_without_returning(db_client: PostgresClient):
    """Test create_many() without returning clause returns an empty list"""
    result = await db_client.table("users").create_many(
        [
            {"name": "Ruth Test", "email": "ruth@example.com", "age": 33},
            {"name": "Sam Test", "email": "sam@example.com", "age": 34},
        ]
    )
    assert result == []

    # Verify both were inserted
    found = await db_client.table("users").where_in(
        "email", ["ruth@example.com", "sam@example.com"]
    ).all()
    assert len(found) == 2

    # Cleanup
    await db_client.delete("users", {"email": "ruth@example.com"})
    await db_client.delete("users", {"email": "sam@example.com"})


@pytest.mark.asyncio
async def test_builder_save_without_returning(db_client: PostgresClient):
    """Test save() without returning clause returns None"""
    user = await db_client.table("users").save(
        {"name": "Tina Test", "email": "tina@example.com", "age": 37}
    )
    assert user is None

    # Cleanup
    await db_client.delete("users", {"email": "tina@example.com"})


@pytest.mark.asyncio
async def test_builder_save_custom_id_field(db_client: PostgresClient):
    """Test save() with a non‑default id_field"""
    # Use email as the id_field
    saved = await db_client.table("users").save(
        {"email": "custom-id@example.com", "name": "Custom ID Test", "age": 42},
        id_field="email",
        returning=["id", "name", "email", "age"],
    )
    assert saved is not None
    assert saved["name"] == "Custom ID Test"
    assert saved["email"] == "custom-id@example.com"

    # Now save again with the same email — should update
    updated = await db_client.table("users").save(
        {"email": "custom-id@example.com", "name": "Custom ID Updated", "age": 43},
        id_field="email",
        returning=["id", "name", "email", "age"],
    )
    assert updated is not None
    assert updated["name"] == "Custom ID Updated"
    assert updated["age"] == 43

    # Cleanup
    await db_client.delete("users", {"email": "custom-id@example.com"})


@pytest.mark.asyncio
async def test_builder_save_id_only_no_update(db_client: PostgresClient):
    """Test save() with only the id_field and no other values returns the existing record"""
    # Create a user first
    created = await db_client.table("users").create(
        {"name": "Uma Test", "email": "uma@example.com", "age": 28},
        returning=["id", "name", "email", "age"],
    )
    record_id = created["id"]

    # Save with only the id (no extra values)
    result = await db_client.table("users").save(
        {"id": record_id},
        returning=["id", "name", "email", "age"],
    )
    assert result is not None
    assert result["name"] == "Uma Test"
    assert result["age"] == 28

    # Cleanup
    await db_client.delete("users", {"email": "uma@example.com"})


# ---------------------------------------------------------------------------
# Edge‑case tests — update, delete, remove
# ---------------------------------------------------------------------------


@pytest.mark.asyncio
async def test_builder_update_zero_rows(db_client: PostgresClient):
    """Test update() that matches zero rows returns 0"""
    count = await (
        db_client.table("users")
        .where("email", "nobody@example.com")
        .update(name="Nobody")
    )
    assert count == 0


@pytest.mark.asyncio
async def test_builder_update_multiple_conditions(db_client: PostgresClient):
    """Test update() with multiple AND conditions"""
    await db_client.table("users").create(
        {"name": "Vera Test", "email": "vera@example.com", "age": 45}
    )

    count = await (
        db_client.table("users")
        .where("email", "vera@example.com")
        .where_eq("age", 45)
        .update(name="Vera Updated", age=46)
    )
    assert count == 1

    user = await db_client.table("users").where("email", "vera@example.com").first()
    assert user["name"] == "Vera Updated"
    assert user["age"] == 46

    # Cleanup
    await db_client.delete("users", {"email": "vera@example.com"})


@pytest.mark.asyncio
async def test_builder_update_with_or_skips_non_eq(db_client: PostgresClient):
    """Test update() with OR conditions — only Eq conditions are used"""
    # Create two test users
    await db_client.table("users").create_many([
        {"name": "Wes Test", "email": "wes@example.com", "age": 38},
        {"name": "Xia Test", "email": "xia@example.com", "age": 39},
    ])

    # Update with OR + Eq: the OR is skipped, only Eq conditions passed through
    count = await (
        db_client.table("users")
        .where("age", 38)
        .or_where("age", 39)
        .update(age=100)
    )
    # Only "age=38" is extracted as a simple condition; the OR is ignored
    # So only the first one is updated
    assert count == 1

    # Verify
    wes = await db_client.table("users").where("email", "wes@example.com").first()
    xia = await db_client.table("users").where("email", "xia@example.com").first()
    assert wes["age"] == 100
    assert xia["age"] == 39  # unchanged because OR was skipped

    # Cleanup
    await db_client.delete("users", {"email": "wes@example.com"})
    await db_client.delete("users", {"email": "xia@example.com"})


@pytest.mark.asyncio
async def test_builder_delete_zero_rows(db_client: PostgresClient):
    """Test delete() that matches zero rows returns 0"""
    count = await (
        db_client.table("users")
        .where("email", "nobody@example.com")
        .delete()
    )
    assert count == 0


@pytest.mark.asyncio
async def test_builder_delete_multiple_conditions(db_client: PostgresClient):
    """Test delete() with multiple AND conditions"""
    await db_client.table("users").create(
        {"name": "Yara Test", "email": "yara@example.com", "age": 29}
    )

    count = await (
        db_client.table("users")
        .where("email", "yara@example.com")
        .where_eq("age", 29)
        .delete()
    )
    assert count == 1

    # Verify gone
    user = await db_client.table("users").where("email", "yara@example.com").first()
    assert user is None


@pytest.mark.asyncio
async def test_builder_remove_no_conditions(db_client: PostgresClient):
    """Test remove() with no conditions deletes all matching rows (safety: use limit)"""
    # Create two test users to delete
    await db_client.table("users").create_many([
        {"name": "Zane Test", "email": "zane@example.com", "age": 22},
        {"name": "Abby Test", "email": "abby@example.com", "age": 23},
    ])

    # remove() on a filtered subset is safe — use where + limit
    count = await (
        db_client.table("users")
        .where_in("email", ["zane@example.com", "abby@example.com"])
        .remove()
    )
    assert count == 2

    # Verify both are gone
    zane = await db_client.table("users").where("email", "zane@example.com").first()
    abby = await db_client.table("users").where("email", "abby@example.com").first()
    assert zane is None
    assert abby is None

    # Seed users should still be intact
    users = await db_client.table("users").all()
    assert len(users) == 4


# ---------------------------------------------------------------------------
# Chaining and boundary tests
# ---------------------------------------------------------------------------


@pytest.mark.asyncio
async def test_builder_create_ignores_prior_where(db_client: PostgresClient):
    """Test that create() ignores previously chained where clauses"""
    user = await (
        db_client.table("users")
        .where("email", "alice@example.com")  # should be irrelevant for create
        .create(
            {"name": "Ben Test", "email": "ben@example.com", "age": 25},
            returning=["id", "name", "email", "age"],
        )
    )
    assert user is not None
    assert user["name"] == "Ben Test"

    # Cleanup
    await db_client.delete("users", {"email": "ben@example.com"})


@pytest.mark.asyncio
async def test_builder_save_ignores_prior_where(db_client: PostgresClient):
    """Test that save() ignores previously chained where clauses"""
    saved = await (
        db_client.table("users")
        .where("email", "alice@example.com")  # should be irrelevant for save
        .save(
            {"name": "Cody Test", "email": "cody@example.com", "age": 26},
            returning=["id", "name", "email", "age"],
        )
    )
    assert saved is not None
    assert saved["name"] == "Cody Test"

    # Cleanup
    await db_client.delete("users", {"email": "cody@example.com"})


@pytest.mark.asyncio
async def test_builder_count_after_multiple_wheres(db_client: PostgresClient):
    """Test count() after chaining multiple where clauses"""
    n = await (
        db_client.table("posts")
        .where("published", True)
        .where_gt("views", 50)
        .count()
    )
    assert n == 2  # First Post (100 views), Bob's Post (75 views)


@pytest.mark.asyncio
async def test_builder_update_offset_ignored(db_client: PostgresClient):
    """Test update() with offset — offset should not interfere with the update"""
    await db_client.table("users").create(
        {"name": "Dax Test", "email": "dax@example.com", "age": 29}
    )

    # offset is irrelevant for mutations but should not cause errors
    count = await (
        db_client.table("users")
        .where("email", "dax@example.com")
        .offset(5)
        .update(age=30)
    )
    assert count == 1

    user = await db_client.table("users").where("email", "dax@example.com").first()
    assert user["age"] == 30

    # Cleanup
    await db_client.delete("users", {"email": "dax@example.com"})


@pytest.mark.asyncio
async def test_builder_delete_offset_ignored(db_client: PostgresClient):
    """Test delete() with offset — offset should not interfere with the delete"""
    await db_client.table("users").create(
        {"name": "Eli Test", "email": "eli@example.com", "age": 31}
    )

    count = await (
        db_client.table("users")
        .where("email", "eli@example.com")
        .offset(10)
        .delete()
    )
    assert count == 1

    user = await db_client.table("users").where("email", "eli@example.com").first()
    assert user is None


@pytest.mark.asyncio
async def test_builder_update_empty_values(db_client: PostgresClient):
    """Test update() with no keyword values returns 0 without error"""
    count = await db_client.table("users").where("age", 30).update()
    assert count == 0
