# models/database/product.py

from sqlalchemy import (
    Boolean,
    Column,
    Float,
    ForeignKey,
    Index,
    Integer,
    String,
    UniqueConstraint,
)
from sqlalchemy.orm import relationship

from app.core.database import Base
from models.database.base import TimestampMixin


class Product(Base, TimestampMixin):
    __tablename__ = "products"

    id = Column(Integer, primary_key=True, index=True)
    vendor_id = Column(Integer, ForeignKey("vendors.id"), nullable=False)
    marketplace_product_id = Column(
        Integer, ForeignKey("marketplace_products.id"), nullable=False
    )

    # Vendor-specific overrides
    product_id = Column(String)  # Vendor's internal SKU
    price = Column(Float)
    sale_price = Column(Float)
    currency = Column(String)
    availability = Column(String)
    condition = Column(String)

    # Vendor-specific metadata
    is_featured = Column(Boolean, default=False)
    is_active = Column(Boolean, default=True)
    display_order = Column(Integer, default=0)

    # Inventory settings
    min_quantity = Column(Integer, default=1)
    max_quantity = Column(Integer)

    # Relationships
    vendor = relationship("Vendor", back_populates="products")
    marketplace_product = relationship("MarketplaceProduct", back_populates="product")
    inventory_entries = relationship(
        "Inventory", back_populates="product", cascade="all, delete-orphan"
    )

    # Constraints
    __table_args__ = (
        UniqueConstraint("vendor_id", "marketplace_product_id", name="uq_product"),
        Index("idx_product_active", "vendor_id", "is_active"),
        Index("idx_product_featured", "vendor_id", "is_featured"),
    )

    def __repr__(self):
        return f"<Product(id={self.id}, vendor_id={self.vendor_id}, product_id='{self.product_id}')>"

    @property
    def total_inventory(self):
        """Calculate total inventory across all locations."""
        return sum(inv.quantity for inv in self.inventory_entries)

    @property
    def available_inventory(self):
        """Calculate available inventory (total - reserved)."""
        return sum(inv.available_quantity for inv in self.inventory_entries)
