from enum import Enum
from typing import Annotated, Optional
from uuid import uuid4
from msgspec import Meta, Struct, field


QuantityInt = Annotated[int, Meta(ge=0, le=2147483647)]
StrictSmallInt = Annotated[int, Meta(ge=0, le=32767)]
PriceFloat = Annotated[float, Meta(ge=0, le=99999999.99)]
ExternalId = Annotated[str, Meta(min_length=1, max_length=32)]


class ColumnItemType(str, Enum):
    PRODUCT = "PRODUCT"
    COMPONENT = "COMPONENT"


class CorrelationId(Struct, rename="camel"):
    correlation_id: str = field(default_factory=lambda: uuid4().hex)


class ColumnsInput(Struct, rename="camel"):
    column_number: StrictSmallInt
    external_product_id: Optional[ExternalId] = None
    old_qty: Optional[QuantityInt] = None
    new_qty: Optional[QuantityInt] = None
    old_price: Optional[PriceFloat] = None
    new_price: Optional[PriceFloat] = None
    select_map: Optional[list[StrictSmallInt]] = None
    item_type: Optional[ColumnItemType] = field(
        default_factory=lambda: ColumnItemType.PRODUCT
    )


class PlanogramInput(CorrelationId, Struct, rename="camel"):
    machine_external_id: ExternalId = field(default="")
    columns: list[ColumnsInput] = field(default_factory=list)


class PlanogramsBulkInputPayload(Struct, rename="camel"):
    planograms: list[PlanogramInput] = field(default_factory=list)
