

from dataclasses import dataclass, field
from datetime import datetime

from configs.firebase import db
from functions.Products import getColorImages
from V2.functions.Images.main import Image
from V2.functions.main import DocumentData, validate
from V2.functions.Products.main import ProductMapping, getByPlatformVariantId
from V2.functions.Products.Variants import Property, Variant, VariantMapping


@dataclass(kw_only=True)
class OrderItem(DocumentData):
    platformOrderItemId:str
    platformOrderId:str
    platformProductId:str
    platformId:str
    shopId:str
    name:str
    image:Image
    price:float
    discount:float
    subtotal:float
    tax:float
    total:float
    variantId:str
    quantity:int
    productId:str = ""
    orderId:str = ""
    index:int=1
    batchId:str|None = None
    batched:bool = False
    cancelled:bool = False
    ignored:bool = False
    shipped:bool = False
    draft:bool = False
    variant:Variant|None = None
    purchaseOrder:bool=False
    printOnDemand:bool=True
    purchaseOrderData:VariantMapping|None = None
    printFilePending:bool|None = False
    metadata:dict = field(default_factory=dict)
    images:list[Image] = field(default_factory=list)
    decorationType:str = "1"
    def __post_init__(self):
        if not self.variant: self.addVariant(variant=None)
        if not self.purchaseOrderData: self.addPoData()
        if not self.ignored and self.purchaseOrderData:
            colorImages = getColorImages(
                        self.productId,
                        self.purchaseOrderData.blankProductId if type(self.purchaseOrderData) != dict else self.purchaseOrderData.get("blankProductId"),
                        self.purchaseOrderData.blankVariantId if type(self.purchaseOrderData) != dict else self.purchaseOrderData.get("blankVariantId"),
                    )
            if colorImages: 
                self.images = colorImages
                self.image = colorImages[0]
        validate(self)

    def get(self, id:str):
        doc = db.document(f"orderItems/{id}").get()
        if doc.exists: return self.from_dict(doc.to_dict())
        
    def addVariant(self, variant:Variant|None):
        if variant: self.variant = variant
        else: self.variant = getByPlatformVariantId(self.platformProductId, self.variantId)
    
    def addPoData(self, purchaseOrderData:dict=None):
        if purchaseOrderData: self.purchaseOrderData=purchaseOrderData
        else: 
            productMapping = ProductMapping.get(self.productId)
            if productMapping:
                self.purchaseOrderData = VariantMapping.get(self.productId, self.variantId)
                if self.purchaseOrderData and not self.purchaseOrderData.placements:
                    self.purchaseOrderData.placements = [i.get("placement") for i in self.purchaseOrderData.images if type(i) == dict]
                self.printOnDemand = productMapping.printOnDemand
                self.draft = not self.printOnDemand
                if productMapping.decorationType in ["3", "7"] and self.purchaseOrderData:
                    printFiles = self.purchaseOrderData.images
                    for image in printFiles:
                        if not image.printFile:
                            self.printFilePending = True
                            break
            try: 
                self.decorationType = self.purchaseOrderData.decorationType if self.purchaseOrderData.decorationType else productMapping.decorationType
            except: 
                self.decorationType = "1" # DTG by default
    def addProperties(self, properties:list[Property]):
        if self.variant: self.variant.properties.extend(properties)

    @classmethod
    def getByOrderId(cls, orderId:str):
        docs = db.collection("orderItems").where("orderId", "==", orderId).get()
        return [cls.from_dict(doc.to_dict()) for doc in docs]

    def cancel(self):
        db.document(f"orderItems/{self.id}").update(dict(
            cancelled=True,
            cancelledAt=datetime.now()
        ))
        self.cancelled = True