from app.models.inventory_management import InventoryItem
from app.contexts.inventory_product import InventoryProductContext
from sqlalchemy.orm import Session
from datetime import datetime
from app.models.tcgplayer_products import TCGPlayerProduct

class InventoryItemContext:
    def __init__(self, item: InventoryItem, db: Session):
        self.item = item
        self.physical_item = item.physical_item
        self.marketplace_listings = item.marketplace_listings
        self.parent = item.parent
        self.children = item.children
        self.product = item.product
        self.db = db

    @property
    def cost_basis(self) -> float:
        return self.item.cost_basis
    
    @property
    def product_id(self) -> int:
        return self.physical_item.product_id
    
    @property
    def product_name(self) -> str:
        return self.product.name if self.product else None
    
    @property
    def item_type(self) -> str:
        return self.physical_item.item_type
    
    @property
    def market_price(self) -> float:
        if not self.product or not self.product.most_recent_tcgplayer_price:
            return 0.0
        return self.product.most_recent_tcgplayer_price.market_price
    
    @property
    def tcg_low_price(self) -> float:
        if not self.product or not self.product.most_recent_tcgplayer_price:
            return 0.0
        return self.product.most_recent_tcgplayer_price.low_price
    
    @property
    def listed_price(self) -> float:
        if not self.marketplace_listings:
            return 0.0
        return self.marketplace_listings[0].listed_price if self.marketplace_listings else 0.0
    
    def top_level_parent(self) -> "InventoryItemContext":
        if self.parent:
            return InventoryItemContext(self.parent, self.db)
        return self
    
    def box_expected_value(self) -> float:
        top_level_parent = self.top_level_parent()
        if 'case' in top_level_parent.item_type:
            return top_level_parent.physical_item.open_event.sealed_case.expected_value
        elif 'box' in top_level_parent.item_type:
            return top_level_parent.physical_item.open_event.sealed_box.expected_value
        else:
            raise ValueError("Unknown top level parent item type")

    def box_acquisition_cost(self) -> float:
        if self.physical_item.transaction_items:
            return self.physical_item.transaction_items[0].unit_price
        elif self.parent:
            return InventoryItemContext(self.parent, self.db).box_acquisition_cost()
        else:
            raise ValueError("Cannot find transaction unit price for this item")
    
    def age_on_marketplace(self) -> int:
        if not self.marketplace_listings:
            return 0
        return (datetime.now() - self.marketplace_listings[0].listing_date).days


class InventoryItemContextFactory:
    def __init__(self, db: Session):
        self.db = db

    def get_context(self, item: InventoryItem) -> InventoryItemContext:
        return InventoryItemContext(item, self.db)
    
    def get_context_for_product(self, product: TCGPlayerProduct) -> InventoryProductContext:
        return InventoryProductContext(product, self.db)
