from pydantic import BaseModel
from typing import Optional, List
from datetime import datetime


class PlanCreate(BaseModel):
    plan_no: str
    plan_date: datetime
    cold_coil_no: Optional[str] = None
    hot_coil_no: Optional[str] = None
    steel_grade: Optional[str] = None
    incoming_thickness: Optional[float] = None
    product_thickness: Optional[float] = None
    deviation_upper: Optional[float] = None
    deviation_lower: Optional[float] = None
    incoming_width: Optional[float] = None
    product_width: Optional[float] = None
    packaging_req: Optional[str] = None
    trim_req: Optional[str] = None
    rolling_mode: Optional[str] = None
    coil_diameter: Optional[float] = None
    split_count: Optional[int] = 1
    next_process: Optional[str] = None
    incoming_weight: Optional[float] = None
    incoming_od: Optional[float] = None
    split_weights: Optional[List[Optional[float]]] = None
    status: Optional[str] = "ready"
    remark: Optional[str] = None


class PlanUpdate(BaseModel):
    plan_date: Optional[datetime] = None
    cold_coil_no: Optional[str] = None
    hot_coil_no: Optional[str] = None
    steel_grade: Optional[str] = None
    incoming_thickness: Optional[float] = None
    product_thickness: Optional[float] = None
    deviation_upper: Optional[float] = None
    deviation_lower: Optional[float] = None
    incoming_width: Optional[float] = None
    product_width: Optional[float] = None
    packaging_req: Optional[str] = None
    trim_req: Optional[str] = None
    rolling_mode: Optional[str] = None
    coil_diameter: Optional[float] = None
    split_count: Optional[int] = None
    next_process: Optional[str] = None
    incoming_weight: Optional[float] = None
    incoming_od: Optional[float] = None
    split_weights: Optional[List[Optional[float]]] = None
    status: Optional[str] = None
    remark: Optional[str] = None


class PlanOut(BaseModel):
    id: int
    plan_no: str
    plan_date: datetime
    status: Optional[str] = None
    cold_coil_no: Optional[str] = None
    hot_coil_no: Optional[str] = None
    steel_grade: Optional[str] = None
    incoming_thickness: Optional[float] = None
    product_thickness: Optional[float] = None
    deviation_upper: Optional[float] = None
    deviation_lower: Optional[float] = None
    incoming_width: Optional[float] = None
    product_width: Optional[float] = None
    packaging_req: Optional[str] = None
    trim_req: Optional[str] = None
    rolling_mode: Optional[str] = None
    coil_diameter: Optional[float] = None
    split_count: Optional[int] = 1
    next_process: Optional[str] = None
    incoming_weight: Optional[float] = None
    incoming_od: Optional[float] = None
    split_weights: Optional[List[Optional[float]]] = None
    remark: Optional[str] = None
    created_by: Optional[str] = None
    created_at: datetime
    # 入口位置 / 上卷鞍座 / 生产联动
    position: Optional[str] = None
    on_saddle: Optional[int] = 0
    saddle_at: Optional[datetime] = None
    run_started_at: Optional[datetime] = None
    run_speed: Optional[float] = 0
    run_length_m: Optional[float] = 0
    produced_at: Optional[datetime] = None
    run_data: Optional[dict] = None

    class Config:
        from_attributes = True


class PlanLogOut(BaseModel):
    id: int
    plan_no: Optional[str] = None
    coil_no: Optional[str] = None
    action: Optional[str] = None
    from_status: Optional[str] = None
    to_status: Optional[str] = None
    position: Optional[str] = None
    operator: Optional[str] = None
    detail: Optional[str] = None
    created_at: datetime

    class Config:
        from_attributes = True


class PlanTemplate(BaseModel):
    """新增计划时回填的"上次录入"模板（不含 plan_no/卷号/时间）"""
    steel_grade: Optional[str] = None
    incoming_thickness: Optional[float] = None
    product_thickness: Optional[float] = None
    deviation_upper: Optional[float] = None
    deviation_lower: Optional[float] = None
    incoming_width: Optional[float] = None
    product_width: Optional[float] = None
    packaging_req: Optional[str] = None
    trim_req: Optional[str] = None
    rolling_mode: Optional[str] = None
    coil_diameter: Optional[float] = None
    split_count: Optional[int] = 1
    next_process: Optional[str] = None
    incoming_weight: Optional[float] = None
    incoming_od: Optional[float] = None
    split_weights: Optional[List[Optional[float]]] = None
