from __future__ import annotations

from datetime import date, datetime
from typing import Literal

from pydantic import BaseModel, ConfigDict, Field, field_validator


QuantityType = Literal["bags", "kg"]


class ThroughputProductBase(BaseModel):
    model_config = ConfigDict(extra="forbid")
    item_id: str | None = Field(default=None, max_length=64)
    name: str = Field(min_length=1, max_length=255)
    client_name: str | None = Field(default=None, max_length=255)
    default_bag_size: float | None = Field(default=None, ge=0)
    is_bulka_default: bool = False
    active: bool = True
    is_stock_item: bool = True
    notes: str | None = Field(default=None, max_length=2000)


class ThroughputProductCreate(ThroughputProductBase):
    pass


class ThroughputProductUpdate(BaseModel):
    model_config = ConfigDict(extra="forbid")
    item_id: str | None = Field(default=None, max_length=64)
    name: str | None = Field(default=None, min_length=1, max_length=255)
    client_name: str | None = Field(default=None, max_length=255)
    default_bag_size: float | None = Field(default=None, ge=0)
    is_bulka_default: bool | None = None
    active: bool | None = None
    is_stock_item: bool | None = None
    notes: str | None = Field(default=None, max_length=2000)


class ThroughputProductRead(ThroughputProductBase):
    id: int
    tenant_id: str
    created_at: datetime
    updated_at: datetime
    model_config = ConfigDict(from_attributes=True)


class ThroughputEntryBase(BaseModel):
    model_config = ConfigDict(extra="forbid")
    production_date: date
    product_id: int | None = None
    product_name_snapshot: str | None = Field(default=None, max_length=255)
    bag_size: float | None = Field(default=None, ge=0)
    scales_checked: bool = True
    label_correct: bool = True
    bag_sealed: bool = True
    pallet_good_condition: bool = True
    for_order: bool = False
    for_stock: bool = False
    job_number: str | None = Field(default=None, max_length=64)
    stock_quantity: float | None = Field(default=None, ge=0)
    sample_box_no: str | None = Field(default=None, max_length=64)
    test_weight_1: float | None = Field(default=None, ge=0)
    test_weight_2: float | None = Field(default=None, ge=0)
    test_weight_3: float | None = Field(default=None, ge=0)
    test_weight_4: float | None = Field(default=None, ge=0)
    test_weight_5: float | None = Field(default=None, ge=0)
    quantity: float = Field(ge=0)
    quantity_type: QuantityType = "bags"
    staff_name: str | None = Field(default=None, max_length=255)
    notes: str | None = Field(default=None, max_length=2000)

    @field_validator("job_number")
    @classmethod
    def _normalize_job_number(cls, value: str | None) -> str | None:
        if value is None:
            return None
        stripped = value.strip()
        return stripped or None

    @field_validator("staff_name")
    @classmethod
    def _normalize_staff(cls, value: str | None) -> str | None:
        if value is None:
            return None
        stripped = value.strip()
        return stripped or None


class ThroughputEntryCreate(ThroughputEntryBase):
    pass


class ThroughputEntryUpdate(BaseModel):
    model_config = ConfigDict(extra="forbid")
    production_date: date | None = None
    product_id: int | None = None
    product_name_snapshot: str | None = Field(default=None, max_length=255)
    bag_size: float | None = Field(default=None, ge=0)
    scales_checked: bool | None = None
    label_correct: bool | None = None
    bag_sealed: bool | None = None
    pallet_good_condition: bool | None = None
    for_order: bool | None = None
    for_stock: bool | None = None
    job_number: str | None = Field(default=None, max_length=64)
    stock_quantity: float | None = Field(default=None, ge=0)
    sample_box_no: str | None = Field(default=None, max_length=64)
    test_weight_1: float | None = Field(default=None, ge=0)
    test_weight_2: float | None = Field(default=None, ge=0)
    test_weight_3: float | None = Field(default=None, ge=0)
    test_weight_4: float | None = Field(default=None, ge=0)
    test_weight_5: float | None = Field(default=None, ge=0)
    quantity: float | None = Field(default=None, ge=0)
    quantity_type: QuantityType | None = None
    staff_name: str | None = Field(default=None, max_length=255)
    notes: str | None = Field(default=None, max_length=2000)


class ThroughputImportResult(BaseModel):
    entries_imported: int
    entries_skipped: int
    products_created: int
    errors: list[str] = Field(default_factory=list)


class ThroughputDeleteAllResult(BaseModel):
    entries_deleted: int


class ThroughputEntryRead(BaseModel):
    id: int
    tenant_id: str
    production_date: date
    product_id: int | None
    product_name_snapshot: str
    bag_size: float | None
    scales_checked: bool
    label_correct: bool
    bag_sealed: bool
    pallet_good_condition: bool
    for_order: bool
    for_stock: bool
    job_number: str | None
    stock_quantity: float | None
    sample_box_no: str | None
    test_weight_1: float | None
    test_weight_2: float | None
    test_weight_3: float | None
    test_weight_4: float | None
    test_weight_5: float | None
    quantity: float
    quantity_type: QuantityType
    calculated_kg: float
    staff_name: str | None
    notes: str | None
    qa_passed: bool
    created_by: str | None
    created_at: datetime
    updated_at: datetime
    model_config = ConfigDict(from_attributes=True)
