from soigia.db import Env, MemoryBackend, Model, PandasBackend, default_registry, fields


def test_db_package_exports_module():
    import soigia

    assert hasattr(soigia, "db")
    assert soigia.db.Model is Model


def test_db_memory_backend_queryset_and_relations():
    class Customer(Model):
        _name = "test.db.customer"

        name = fields.String(required=True)
        vip = fields.Boolean(default=False)

    class Order(Model):
        _name = "test.db.order"

        customer = fields.ForeignKey("test.db.customer")
        total = fields.Float(default=0)
        lines = fields.OneToMany("test.db.line", "order")

    class Line(Model):
        _name = "test.db.line"

        order = fields.ForeignKey("test.db.order")
        amount = fields.Float(default=0)

    env = Env(default_registry, MemoryBackend())

    customer = env["test.db.customer"].create({"name": "Alice", "vip": True})
    order = env["test.db.order"].create({"customer": customer, "total": 12.5})
    env["test.db.line"].create({"order": order, "amount": 5})
    env["test.db.line"].create({"order": order, "amount": 7.5})

    assert customer.name == "Alice"
    assert customer.vip is True
    assert order.customer.name == "Alice"
    assert order.lines.ids == [1, 2]
    assert env["test.db.order"].search([("total", "gt", 10)]).first().id == order.id
    assert env["test.db.order"].filter(total__gte=10).first().id == order.id


def test_db_inherit_extension_merges_fields_and_methods():
    class SaleOrder(Model):
        _name = "test.db.sale.order"

        name = fields.String(required=True)
        amount = fields.Float(default=0)

    class SaleOrderExtension(Model):
        _inherit = "test.db.sale.order"

        state = fields.String(default="draft")

        def action_confirm(self):
            self.state = "confirmed"
            self.save()
            return self.state

    env = Env(default_registry, MemoryBackend())
    order = env["test.db.sale.order"].create({"name": "SO-1", "amount": 100})

    assert order.state == "draft"
    assert order.action_confirm() == "confirmed"
    assert env["test.db.sale.order"].browse(order.id).state == "confirmed"


def test_db_pandas_backend_search_and_order():
    class Product(Model):
        _name = "test.db.product"

        name = fields.String(required=True)
        price = fields.Float(default=0)

    env = Env(default_registry, PandasBackend())
    env["test.db.product"].create({"name": "B", "price": 20})
    env["test.db.product"].create({"name": "A", "price": 10})

    products = env["test.db.product"].objects.filter(price__gte=10).order_by("-price").all()

    assert products.ids == [1, 2]
    assert [product.name for product in products] == ["B", "A"]
