# app/modules/orders/models/order_item_exception.py
"""
Order Item Exception model for tracking unmatched products during marketplace imports.

When a marketplace order contains a GTIN that doesn't match any product in the
store's catalog, the order is still imported but the item is linked to a
placeholder product and an exception is recorded here for resolution.
"""

from sqlalchemy import (
    Column,
    DateTime,
    ForeignKey,
    Index,
    Integer,
    String,
    Text,
)
from sqlalchemy.orm import relationship

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


class OrderItemException(Base, TimestampMixin):
    """
    Tracks unmatched order items requiring admin/store resolution.

    When a marketplace order is imported and a product cannot be found by GTIN,
    the order item is linked to a placeholder product and this exception record
    is created. The order cannot be confirmed until all exceptions are resolved.
    """

    __tablename__ = "order_item_exceptions"

    id = Column(Integer, primary_key=True, index=True)

    # Link to the order item (one-to-one)
    order_item_id = Column(
        Integer,
        ForeignKey("order_items.id", ondelete="CASCADE"),
        nullable=False,
        unique=True,
    )

    # Store ID for efficient querying (denormalized from order)
    store_id = Column(
        Integer, ForeignKey("stores.id"), nullable=False, index=True
    )

    # Original data from marketplace (preserved for matching)
    original_gtin = Column(String(50), nullable=True, index=True)
    original_product_name = Column(String(500), nullable=True)
    original_sku = Column(String(100), nullable=True)

    # Exception classification
    # product_not_found: GTIN not in store catalog
    # gtin_mismatch: GTIN format issue
    # duplicate_gtin: Multiple products with same GTIN
    exception_type = Column(
        String(50), nullable=False, default="product_not_found"
    )

    # Resolution status
    # pending: Awaiting resolution
    # resolved: Product has been assigned
    # ignored: Marked as ignored (still blocks confirmation)
    status = Column(String(50), nullable=False, default="pending", index=True)

    # Resolution details (populated when resolved)
    resolved_product_id = Column(
        Integer, ForeignKey("products.id"), nullable=True
    )
    resolved_at = Column(DateTime(timezone=True), nullable=True)
    resolved_by = Column(Integer, ForeignKey("users.id"), nullable=True)
    resolution_notes = Column(Text, nullable=True)

    # Relationships
    order_item = relationship("OrderItem", back_populates="exception")
    store = relationship("Store")
    resolved_product = relationship("Product")
    resolver = relationship("User")

    # Composite indexes for common queries
    __table_args__ = (
        Index("idx_exception_store_status", "store_id", "status"),
        Index("idx_exception_gtin", "store_id", "original_gtin"),
    )

    def __repr__(self):
        return (
            f"<OrderItemException(id={self.id}, "
            f"order_item_id={self.order_item_id}, "
            f"gtin='{self.original_gtin}', "
            f"status='{self.status}')>"
        )

    @property
    def is_pending(self) -> bool:
        """Check if exception is pending resolution."""
        return self.status == "pending"

    @property
    def is_resolved(self) -> bool:
        """Check if exception has been resolved."""
        return self.status == "resolved"

    @property
    def is_ignored(self) -> bool:
        """Check if exception has been ignored."""
        return self.status == "ignored"

    @property
    def blocks_confirmation(self) -> bool:
        """Check if this exception blocks order confirmation."""
        # Both pending and ignored exceptions block confirmation
        return self.status in ("pending", "ignored")
