# tests/unit/models/database/test_inventory.py
"""Unit tests for Inventory database model."""

import pytest
from sqlalchemy.exc import IntegrityError

from app.modules.inventory.models import Inventory


@pytest.mark.unit
@pytest.mark.database
class TestInventoryModel:
    """Test Inventory model."""

    def test_inventory_creation_with_product(self, db, test_store, test_product):
        """Test Inventory model linked to product."""
        inventory = Inventory(
            product_id=test_product.id,
            store_id=test_store.id,
            warehouse="strassen",
            bin_location="SA-10-01",
            quantity=150,
            reserved_quantity=10,
            gtin=test_product.marketplace_product.gtin,
        )

        db.add(inventory)
        db.commit()
        db.refresh(inventory)

        assert inventory.id is not None
        assert inventory.product_id == test_product.id
        assert inventory.store_id == test_store.id
        assert inventory.bin_location == "SA-10-01"
        assert inventory.quantity == 150
        assert inventory.reserved_quantity == 10
        assert inventory.available_quantity == 140  # 150 - 10

    def test_inventory_unique_product_location(self, db, test_store, test_product):
        """Test unique constraint on product_id + warehouse + bin_location."""
        inventory1 = Inventory(
            product_id=test_product.id,
            store_id=test_store.id,
            warehouse="strassen",
            bin_location="SA-10-01",
            quantity=100,
        )
        db.add(inventory1)
        db.commit()

        # Same product + warehouse + bin_location should fail
        with pytest.raises(IntegrityError):
            inventory2 = Inventory(
                product_id=test_product.id,
                store_id=test_store.id,
                warehouse="strassen",
                bin_location="SA-10-01",
                quantity=50,
            )
            db.add(inventory2)
            db.commit()

    def test_inventory_same_product_different_location(
        self, db, test_store, test_product
    ):
        """Test same product can have inventory in different locations."""
        inventory1 = Inventory(
            product_id=test_product.id,
            store_id=test_store.id,
            warehouse="strassen",
            bin_location="SA-10-01",
            quantity=100,
        )
        db.add(inventory1)
        db.commit()

        # Same product in different bin_location should succeed
        inventory2 = Inventory(
            product_id=test_product.id,
            store_id=test_store.id,
            warehouse="strassen",
            bin_location="SA-10-02",
            quantity=50,
        )
        db.add(inventory2)
        db.commit()
        db.refresh(inventory2)

        assert inventory2.id is not None
        assert inventory2.bin_location == "SA-10-02"

    def test_inventory_default_values(self, db, test_store, test_product):
        """Test Inventory model default values."""
        inventory = Inventory(
            product_id=test_product.id,
            store_id=test_store.id,
            warehouse="strassen",
            bin_location="DEF-01-01",
            quantity=100,
        )
        db.add(inventory)
        db.commit()
        db.refresh(inventory)

        assert inventory.reserved_quantity == 0  # Default
        assert inventory.available_quantity == 100  # quantity - reserved

    def test_inventory_available_quantity_property(self, db, test_store, test_product):
        """Test available_quantity computed property."""
        inventory = Inventory(
            product_id=test_product.id,
            store_id=test_store.id,
            warehouse="strassen",
            bin_location="PROP-01-01",
            quantity=200,
            reserved_quantity=50,
        )
        db.add(inventory)
        db.commit()
        db.refresh(inventory)

        assert inventory.available_quantity == 150  # 200 - 50

    def test_inventory_relationships(self, db, test_store, test_product):
        """Test Inventory relationships."""
        inventory = Inventory(
            product_id=test_product.id,
            store_id=test_store.id,
            warehouse="strassen",
            bin_location="REL-01-01",
            quantity=100,
        )
        db.add(inventory)
        db.commit()
        db.refresh(inventory)

        assert inventory.product is not None
        assert inventory.store is not None
        assert inventory.product.id == test_product.id
        assert inventory.store.id == test_store.id

    def test_inventory_without_gtin(self, db, test_store, test_product):
        """Test Inventory can be created without GTIN."""
        inventory = Inventory(
            product_id=test_product.id,
            store_id=test_store.id,
            warehouse="strassen",
            bin_location="NOGTIN-01-01",
            quantity=100,
        )
        db.add(inventory)
        db.commit()
        db.refresh(inventory)

        assert inventory.gtin is None
