import dataclasses
from dataclasses import Field, asdict, dataclass

from configs.firebase import db
from V2.functions.Images.main import Image
from V2.functions.main import DocumentData, validate


@dataclass
class Property:
    name: str
    value: str
    id: str | None = ""
    
    def from_dict(cls, data):
        data = {**data}
        return cls(**{
            field.name: convert(field, data.get(field.name)) for field in dataclasses.fields(cls)
        })
    
    def __post_init__(self):
         for field in dataclasses.fields(self):
            value = getattr(self, field.name)
            if type(value) != field.type: setattr(self, field.name, convert(field, value))

    def to_dict(self):
        return asdict(self)


def convert(field:Field, value):
    if value is None: return None
    if field.type == int: return int(value)
    elif field.type == str: return str(value)
    elif field.type == float: return float(value)
    return value

@dataclass(kw_only=True)
class Variant(DocumentData):
    price: int | float
    properties: list[Property]
    deleted:bool = False
    sku:str|None = None
    productId: str|None = None
    name: str|None =None

    @classmethod
    def get(cls, productId:str, variantId:str):
        snap = db.document(f"products/{productId}/variants/{variantId}").get()
        if snap.exists:return cls.from_dict({"id": snap.id, **snap.to_dict()})
    
    @classmethod
    def getAll(cls, productId:str):
        ref = db.collection(f"products/{productId}/variants").get()
        return [cls.from_dict({"id": doc.id, **doc.to_dict()}) for doc in ref]
@dataclass
class VariantMapping(DocumentData):
    blankProductId:str
    blankVariantId:str
    productId:str
    sku:str
    images:list[Image]
    placements:list[str]
    ignored:bool=False
    decorationType:str = "1"

    @classmethod
    def get(cls, productId:str, variantId:str):
        ref = db.document(f"productsMapping/{productId}/variantsMapping/{variantId}").get()
        if ref.exists: return cls.from_dict(ref.to_dict())
        return None
    
    @classmethod
    def getAll(cls, productId:str):
        ref = db.collection(f"productsMapping/{productId}/variantsMapping").get()
        return [cls.from_dict(doc.to_dict()) for doc in ref]

    def __post_init__(self):
        validate(self)