"""
Test the on_delete cascade options for ForeignKey fields.

This test demonstrates all four cascade options:
- CASCADE: Delete dependent objects when the parent is deleted
- SET_NULL: Set the foreign key to NULL when the parent is deleted
- SET_DEFAULT: Set the foreign key to its default value when the parent is deleted
- PROTECT: Prevent deletion of the parent when dependent objects exist
"""

import sys
import os

sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))

from atomsql.orm.models import Model
from atomsql.orm.fields import CharField, ForeignKey
from atomsql.orm.fields import CASCADE, SET_NULL, SET_DEFAULT, PROTECT
from atomsql.core.db import Database


# Test models
class Category(Model):
    name = CharField(max_length=100)

    def __repr__(self):
        return f"Category(id={self.id}, name='{self.name}')"


class Product(Model):
    name = CharField(max_length=100)
    category_cascade = ForeignKey(Category, on_delete=CASCADE)
    category_set_null = ForeignKey(Category, nullable=True, on_delete=SET_NULL)
    category_set_default = ForeignKey(Category, default=1, on_delete=SET_DEFAULT)
    category_protect = ForeignKey(Category, on_delete=PROTECT)

    def __repr__(self):
        return f"Product(id={self.id}, name='{self.name}', cascade={self.category_cascade_id}, set_null={self.category_set_null_id}, set_default={self.category_set_default_id}, protect={self.category_protect_id})"


def test_cascade_functionality():
    """Test all cascade options"""
    # Create database and register models
    db = Database("sqlite:///:memory:")
    db.register(Category)
    db.register(Product)

    # Create test data
    electronics = Category.create(name="Electronics")
    books = Category.create(name="Books")
    default_cat = Category.create(name="Default")
    protected_cat = Category.create(name="Protected")

    print("Created categories:")
    print(f"  {electronics}")
    print(f"  {books}")
    print(f"  {default_cat}")
    print(f"  {protected_cat}")

    # Create products with different FK relationships
    phone = Product.create(
        name="Phone",
        category_cascade=electronics,  # Will cascade delete
        category_set_null=books,  # Will set to null
        category_set_default=books,  # Will set to default (1)
        category_protect=protected_cat,  # Will protect
    )

    laptop = Product.create(
        name="Laptop",
        category_cascade=books,  # Different cascade target
        category_set_null=electronics,  # Will set to null
        category_set_default=electronics,  # Will set to default (1)
        category_protect=protected_cat,  # Will protect
    )

    print("\nCreated products:")
    print(f"  {phone}")
    print(f"  {laptop}")

    # Test PROTECT first (create a product that references protected category)
    print("\n--- Testing PROTECT ---")
    print("Trying to delete protected category (should fail)")

    try:
        protected_cat.delete()
        print("ERROR: Protected category was deleted (should have failed)")
    except ValueError as e:
        print(f"PROTECT worked correctly: {e}")
    except Exception as e:
        print(f"Unexpected error: {e}")

    # Test SET_NULL: Delete electronics category
    print("\n--- Testing SET_NULL ---")
    print("Deleting electronics category (should set some FKs to NULL)")

    try:
        electronics.delete()

        # Check what happened to products
        remaining_products = list(Product.all())
        print(f"Remaining products after SET_NULL test: {len(remaining_products)}")
        for product in remaining_products:
            print(f"  {product}")

    except Exception as e:
        print(f"Error during SET_NULL test: {e}")

    # Test CASCADE: Delete books category (should cascade delete phone)
    print("\n--- Testing CASCADE ---")
    print("Deleting books category (should cascade delete laptop)")

    try:
        books.delete()

        # Check what happened
        remaining_products = list(Product.all())
        print(f"Remaining products after CASCADE delete: {len(remaining_products)}")
        for product in remaining_products:
            print(f"  {product}")

    except Exception as e:
        print(f"Error during cascade test: {e}")

    print("\nTest completed!")


if __name__ == "__main__":
    test_cascade_functionality()
