"""
Pydantic schemas for the Production Tracking module.
"""
from pydantic import BaseModel, Field
from typing import Optional, List
from uuid import UUID
from datetime import datetime


# ── Scan ──────────────────────────────────────────────────
class ScanRequest(BaseModel):
    chassis_no: str = Field(..., description="Chassis number or QR code value")
    station_id: UUID
    scan_mode: str = Field(default="QR_SCAN", pattern="^(QR_SCAN|MANUAL_ENTRY)$")
    remarks: Optional[str] = None

class ScanResponse(BaseModel):
    event_type: str          # ARRIVAL | COMPLETION
    chassis_no: str
    station_name: str
    message: str
    log_id: UUID
    elapsed_minutes: Optional[int] = None
    is_overdue: bool = False

    class Config:
        from_attributes = True


# ── Delay Reason ──────────────────────────────────────────
class DelayReasonOut(BaseModel):
    delay_reason_id: UUID
    reason_code: str
    reason_label: str
    category: str
    is_active: bool

    class Config:
        from_attributes = True

class DelayReasonCreate(BaseModel):
    reason_code: str
    reason_label: str
    category: str = "OPERATIONAL"

class DelayReasonUpdate(BaseModel):
    reason_label: Optional[str] = None
    category: Optional[str] = None
    is_active: Optional[bool] = None


# ── Delay Log ─────────────────────────────────────────────
class DelayLogRequest(BaseModel):
    delay_reason_id: UUID
    delay_remarks: Optional[str] = None


# ── Hold ──────────────────────────────────────────────────
class HoldCreate(BaseModel):
    chassis_no: str
    hold_type: str
    hold_reason: str
    station_id: Optional[UUID] = None

class HoldResolve(BaseModel):
    resolution_notes: Optional[str] = None

class HoldOut(BaseModel):
    hold_id: UUID
    chassis_id: UUID
    chassis_no: Optional[str] = None
    station_id: Optional[UUID] = None
    station_name: Optional[str] = None
    hold_type: str
    hold_reason: str
    raised_by: Optional[UUID] = None
    raised_by_name: Optional[str] = None
    raised_at: datetime
    resolved_by: Optional[UUID] = None
    resolved_at: Optional[datetime] = None
    resolution_notes: Optional[str] = None
    status: str

    class Config:
        from_attributes = True


# ── Station Live View ─────────────────────────────────────
class ChassisAtStation(BaseModel):
    chassis_id: UUID
    chassis_no: str
    log_id: UUID
    arrived_at: datetime
    elapsed_minutes: int
    cycle_time_min: Optional[int] = None
    is_overdue: bool = False
    is_warning: bool = False        # > alert_threshold but < cycle_time
    hold_status: str = "NONE"
    delay_reason: Optional[str] = None
    model_name: Optional[str] = None

class StationLiveView(BaseModel):
    station_id: UUID
    station_name: str
    station_code: str
    sequence_no: Optional[int] = None
    requires_qa: bool = False
    cycle_time_min: Optional[int] = None
    alert_threshold_min: Optional[int] = None
    chassis_count: int = 0
    overdue_count: int = 0
    chassis_list: List[ChassisAtStation] = []


# ── Dashboard ─────────────────────────────────────────────
class DashboardKPIs(BaseModel):
    wip_count: int = 0
    completed_today: int = 0
    on_hold_count: int = 0
    overdue_count: int = 0

class UnplacedChassis(BaseModel):
    """In production (WIP) but not checked in at any station yet."""
    chassis_id: UUID
    chassis_no: str
    model_name: Optional[str] = None
    hold_status: str = "NONE"
    since: Optional[datetime] = None

class DashboardResponse(BaseModel):
    kpis: DashboardKPIs
    stations: List[StationLiveView]
    unplaced: List[UnplacedChassis] = []


# ── Chassis Timeline ──────────────────────────────────────
class TimelineEntry(BaseModel):
    log_id: UUID
    station_id: UUID
    station_name: str
    event_type: str
    scanned_at: datetime
    elapsed_minutes: Optional[int] = None
    is_overdue: bool = False
    delay_reason: Optional[str] = None
    delay_remarks: Optional[str] = None
    status: str

    class Config:
        from_attributes = True


# ── Overdue ───────────────────────────────────────────────
class OverdueEntry(BaseModel):
    chassis_id: UUID
    chassis_no: str
    station_name: str
    arrived_at: datetime
    elapsed_minutes: int
    cycle_time_min: Optional[int] = None
    delay_reason: Optional[str] = None
    delay_remarks: Optional[str] = None
    delay_logged: bool = False


# ── Bottleneck Analytics ──────────────────────────────────
class StationBottleneck(BaseModel):
    station_id: UUID
    station_name: str
    avg_elapsed_min: float
    cycle_time_min: Optional[int] = None
    total_completions: int
    overdue_count: int
    overdue_pct: float
