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

import pytest
from sqlalchemy.exc import IntegrityError

from models.database.inventory import Inventory


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

    def test_inventory_creation_with_product(self, db, test_vendor, test_product):
        """Test Inventory model linked to product."""
        inventory = Inventory(
            product_id=test_product.id,
            vendor_id=test_vendor.id,
            location="WAREHOUSE_A",
            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.vendor_id == test_vendor.id
        assert inventory.location == "WAREHOUSE_A"
        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_vendor, test_product):
        """Test unique constraint on product_id + location."""
        inventory1 = Inventory(
            product_id=test_product.id,
            vendor_id=test_vendor.id,
            location="WAREHOUSE_A",
            quantity=100,
        )
        db.add(inventory1)
        db.commit()

        # Same product + location should fail
        with pytest.raises(IntegrityError):
            inventory2 = Inventory(
                product_id=test_product.id,
                vendor_id=test_vendor.id,
                location="WAREHOUSE_A",
                quantity=50,
            )
            db.add(inventory2)
            db.commit()

    def test_inventory_same_product_different_location(
        self, db, test_vendor, test_product
    ):
        """Test same product can have inventory in different locations."""
        inventory1 = Inventory(
            product_id=test_product.id,
            vendor_id=test_vendor.id,
            location="WAREHOUSE_A",
            quantity=100,
        )
        db.add(inventory1)
        db.commit()

        # Same product in different location should succeed
        inventory2 = Inventory(
            product_id=test_product.id,
            vendor_id=test_vendor.id,
            location="WAREHOUSE_B",
            quantity=50,
        )
        db.add(inventory2)
        db.commit()
        db.refresh(inventory2)

        assert inventory2.id is not None
        assert inventory2.location == "WAREHOUSE_B"

    def test_inventory_default_values(self, db, test_vendor, test_product):
        """Test Inventory model default values."""
        inventory = Inventory(
            product_id=test_product.id,
            vendor_id=test_vendor.id,
            location="DEFAULT_LOC",
            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_vendor, test_product):
        """Test available_quantity computed property."""
        inventory = Inventory(
            product_id=test_product.id,
            vendor_id=test_vendor.id,
            location="PROP_TEST",
            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_vendor, test_product):
        """Test Inventory relationships."""
        inventory = Inventory(
            product_id=test_product.id,
            vendor_id=test_vendor.id,
            location="REL_TEST",
            quantity=100,
        )
        db.add(inventory)
        db.commit()
        db.refresh(inventory)

        assert inventory.product is not None
        assert inventory.vendor is not None
        assert inventory.product.id == test_product.id
        assert inventory.vendor.id == test_vendor.id

    def test_inventory_without_gtin(self, db, test_vendor, test_product):
        """Test Inventory can be created without GTIN."""
        inventory = Inventory(
            product_id=test_product.id,
            vendor_id=test_vendor.id,
            location="NO_GTIN",
            quantity=100,
        )
        db.add(inventory)
        db.commit()
        db.refresh(inventory)

        assert inventory.gtin is None
