"""
VibeDB Query System Test

Demonstrates all query operators and Q builder functionality.
"""

from vibedb import VibeDB, Q


def main():
    print("🔍 VibeDB Query System Test\n")

    # Create database
    db = VibeDB(":memory:")
    users = db.collection("users")

    # Insert test data
    print("📝 Inserting test data...")
    users.insert_many([
        {"name": "Alice", "age": 28, "email": "alice@example.com", "status": "active", "tags": ["python", "ml"]},
        {"name": "Bob", "age": 35, "email": "bob@example.com", "status": "active", "tags": ["javascript", "react"]},
        {"name": "Charlie", "age": 22, "email": "charlie@gmail.com", "status": "pending", "tags": ["python", "django"]},
        {"name": "Diana", "age": 45, "email": "diana@example.com", "status": "inactive", "tags": ["java", "spring"]},
        {"name": "Eve", "age": 30, "email": "eve@gmail.com", "status": "active", "tags": ["python", "ml", "data"]},
    ])
    print(f"  ✓ Inserted {users.count()} users\n")

    # Test 1: Comparison operators
    print("📊 Test 1: Comparison Operators")
    print("  Query: age >= 30")
    results = users.find({"age": {"$gte": 30}})
    print(f"  Results: {[u.name for u in results]}")

    print("\n  Query: Q.gte('age', 30) & Q.lt('age', 40)")
    results = users.find(Q.gte("age", 30) & Q.lt("age", 40))
    print(f"  Results: {[u.name for u in results]}")

    # Test 2: String operators
    print("\n📧 Test 2: String Operators")
    print("  Query: email contains '@example.com'")
    results = users.find({"email": {"$contains": "@example.com"}})
    print(f"  Results: {[u.name for u in results]}")

    print("\n  Query: name starts with 'A'")
    results = users.find(Q.prefix("name", "A"))
    print(f"  Results: {[u.name for u in results]}")

    # Test 3: IN operator
    print("\n📋 Test 3: IN Operator")
    print("  Query: status in ['active', 'pending']")
    results = users.find({"status": {"$in": ["active", "pending"]}})
    print(f"  Results: {[u.name for u in results]}")

    print("\n  Query: status not in ['inactive']")
    results = users.find(Q.nin("status", ["inactive"]))
    print(f"  Results: {[u.name for u in results]}")

    # Test 4: Array operators
    print("\n🏷️  Test 4: Array Operators")
    print("  Query: tags contains 'python'")
    results = users.find({"tags": {"$has": "python"}})
    print(f"  Results: {[u.name for u in results]}")

    print("\n  Query: tags has any of ['ml', 'data']")
    results = users.find(Q.has_any("tags", ["ml", "data"]))
    print(f"  Results: {[u.name for u in results]}")

    print("\n  Query: tags has all of ['python', 'ml']")
    results = users.find(Q.has_all("tags", ["python", "ml"]))
    print(f"  Results: {[u.name for u in results]}")

    # Test 5: Logical operators
    print("\n🔀 Test 5: Logical Operators (AND)")
    print("  Query: (age >= 30 AND status = 'active')")
    results = users.find(Q.gte("age", 30) & Q.eq("status", "active"))
    print(f"  Results: {[u.name for u in results]}")

    print("\n  Query: (status = 'active' OR status = 'pending')")
    results = users.find(Q.eq("status", "active") | Q.eq("status", "pending"))
    print(f"  Results: {[u.name for u in results]}")

    print("\n  Query: NOT (status = 'inactive')")
    results = users.find(~Q.eq("status", "inactive"))
    print(f"  Results: {[u.name for u in results]}")

    # Test 6: Sorting
    print("\n📊 Test 6: Sorting")
    print("  Query: All users sorted by age (descending)")
    results = users.find().sort("age", -1)
    for u in results:
        print(f"    {u.name}: {u.age}")

    # Test 7: Pagination
    print("\n📄 Test 7: Pagination")
    print("  Query: Skip 2, limit 2")
    results = users.find().sort("name").skip(2).limit(2)
    print(f"  Results: {[u.name for u in results]}")

    # Test 8: Field projection
    print("\n🎯 Test 8: Field Projection")
    print("  Query: Only name and email")
    results = users.find(Q.eq("status", "active")).project(["name", "email"])
    for u in results:
        print(f"    {u.name}: {u.email} (age: {u.age})")  # age should be None

    # Test 9: Complex query
    print("\n🎪 Test 9: Complex Query")
    print("  Query: (age between 25-35 AND status='active') OR has 'ml' tag")
    complex_query = (Q.gte("age", 25) & Q.lte("age", 35) & Q.eq("status", "active")) | Q.has("tags", "ml")
    results = users.find(complex_query)
    print(f"  Results: {[u.name for u in results]}")

    # Test 10: Count
    print("\n📊 Test 10: Count")
    count_active = users.find(Q.eq("status", "active")).count()
    count_python = users.find(Q.has("tags", "python")).count()
    print(f"  Active users: {count_active}")
    print(f"  Python users: {count_python}")

    # Test 11: First/find_one
    print("\n🔍 Test 11: Find One")
    user = users.find_one(Q.contains("email", "@gmail.com"))
    if user:
        print(f"  First Gmail user: {user.name}")

    db.close()
    print("\n✅ All tests completed!")


if __name__ == "__main__":
    main()
