from datetime import datetime

from pydantic import BaseModel, ConfigDict, Field


class ProductCostItemBase(BaseModel):
    client_category: str = Field(min_length=1, max_length=255)
    item_id: str | None = Field(default=None, max_length=128)
    product_name: str = Field(min_length=1, max_length=255)
    mix_product_name: str = Field(min_length=1, max_length=255)
    unit_type: str = "Standard"
    own_bag: str | None = None
    unit_kg: float | None = Field(default=None, gt=0)
    items_per_pallet: int | None = Field(default=None, gt=0)
    bagging_process: str | None = Field(default=None, max_length=128)
    manual_distributor_margin: float | None = Field(default=None, ge=0, lt=1)
    manual_wholesale_margin: float | None = Field(default=None, ge=0, lt=1)


class ProductCostItemCreate(ProductCostItemBase):
    pass


class ProductCostItemUpdate(BaseModel):
    model_config = ConfigDict(extra="forbid")
    client_category: str | None = Field(default=None, min_length=1, max_length=255)
    item_id: str | None = Field(default=None, max_length=128)
    product_name: str | None = Field(default=None, min_length=1, max_length=255)
    mix_product_name: str | None = Field(default=None, min_length=1, max_length=255)
    unit_type: str | None = None
    own_bag: str | None = None
    unit_kg: float | None = Field(default=None, gt=0)
    items_per_pallet: int | None = Field(default=None, gt=0)
    bagging_process: str | None = Field(default=None, max_length=128)
    manual_distributor_margin: float | None = Field(default=None, ge=0, lt=1)
    manual_wholesale_margin: float | None = Field(default=None, ge=0, lt=1)


class ProductCostItemRead(ProductCostItemBase):
    id: int
    tenant_id: str
    cleaned_product_cost_per_kg: float | None
    grading_cost_per_kg: float | None
    bagging_cost_per_kg: float | None
    cracking_cost_per_kg: float | None
    bag_cost_per_unit: float | None
    freight_cost_per_unit: float | None
    finished_product_delivered_cost: float | None
    distributor_price: float | None
    wholesale_price: float | None
    warnings: list[str]
    created_at: datetime
    updated_at: datetime


class ProductCostBaseInputRead(BaseModel):
    grading_per_tonne: float
    grading_per_kg: float
    cracking_per_tonne: float
    cracking_per_kg: float


class ProductCostBaseInputUpdate(ProductCostBaseInputRead):
    pass


class ProductCostNamedInputRead(BaseModel):
    key: str
    label: str
    cost: float


class ProductCostClientInputRead(BaseModel):
    client_category: str
    distributor_margin: float | None
    wholesale_margin: float | None


class ProductCostInputsRead(BaseModel):
    base: ProductCostBaseInputRead
    processes: list[ProductCostNamedInputRead]
    clients: list[ProductCostClientInputRead]
    bags: list[ProductCostNamedInputRead]
    freight: list[ProductCostNamedInputRead]


class ProductCostInputsUpdate(BaseModel):
    model_config = ConfigDict(extra="forbid")
    base: ProductCostBaseInputUpdate | None = None
    processes: list[ProductCostNamedInputRead] | None = None
    clients: list[ProductCostClientInputRead] | None = None
    bags: list[ProductCostNamedInputRead] | None = None
    freight: list[ProductCostNamedInputRead] | None = None


class ProductCostRecalculateAllRead(BaseModel):
    recalculated: int
