from pydantic import BaseModel, Field
from typing import Optional, List, Dict, Any
from uuid import UUID
from datetime import date, time, datetime
from decimal import Decimal

class UpdateArrivalRequest(BaseModel):
    arrival_date: date
    remark: str = Field(..., min_length=1)
    yard_location: Optional[str] = None


class CheckpointOut(BaseModel):
    checkpoint_id: UUID
    checkpoint_code: str
    checkpoint_name: str
    sequence_no: int
    model_config = {"from_attributes": True, "protected_namespaces": ()}


class MovementItemOut(BaseModel):
    item_id: UUID
    item_code: str
    item_label: str
    sequence_no: int
    model_config = {"from_attributes": True, "protected_namespaces": ()}


class QaItemOut(BaseModel):
    item_id: UUID
    zone_name: str
    checkpoint_text: str
    sequence_no: int
    model_config = {"from_attributes": True, "protected_namespaces": ()}


class QaItemCreate(BaseModel):
    zone_name: str
    checkpoint_text: str
    sequence_no: Optional[int] = 0


class QaItemUpdate(BaseModel):
    zone_name: Optional[str] = None
    checkpoint_text: Optional[str] = None
    sequence_no: Optional[int] = None


class ModelOut(BaseModel):
    model_id: UUID
    model_number: str
    model_config = {"from_attributes": True, "protected_namespaces": ()}


class HandoverPartOut(BaseModel):
    part_id: UUID
    sr_no: Optional[int] = None
    part_name: str
    fuel_applicability: str
    model_config = {"from_attributes": True, "protected_namespaces": ()}


class HandoverPartCreate(BaseModel):
    part_name: str
    fuel_applicability: Optional[str] = 'ALL'


class YardMastersOut(BaseModel):
    checkpoints: List[CheckpointOut]
    movement_items: List[MovementItemOut]
    qa_items: List[QaItemOut]
    models: List[ModelOut]
    handover_parts: List[HandoverPartOut]


class ChassisCreate(BaseModel):
    chassis_no: str
    model_id: Optional[UUID] = None
    fuel_type: str = 'DIESEL'
    light_type: Optional[str] = None
    voltage: Optional[str] = None
    yard_location: Optional[str] = None
    transport_id: Optional[str] = None
    dealer_id: Optional[str] = None
    client_id: Optional[str] = None
    source_type: str = 'SALES_ORDER'
    build_order_id: Optional[UUID] = None
    fuel_receiving_qty: Optional[Decimal] = None
    arrival_date: date
    remarks: Optional[str] = None

    model_config = {"protected_namespaces": ()}


class ChassisListItem(BaseModel):
    chassis_id: UUID
    chassis_no: str
    model_name: Optional[str] = None
    fuel_type: str
    yard_location: Optional[str] = None
    dealer_name: Optional[str] = None
    client_name: Optional[str] = None
    transport_name: Optional[str] = None
    arrival_date: date
    arrival_remark: Optional[str] = None
    da_lite_status: str
    da_lite_remarks: Optional[str] = None
    da_lite_photo_url: Optional[str] = None
    current_status: str
    tracking_status: str = 'CHASSIS_IN'
    current_station_name: Optional[str] = None
    station_completed_at: Optional[datetime] = None
    csp_count: int = 0
    doc_count: int = 0

    model_config = {"from_attributes": True, "protected_namespaces": ()}


class DaLiteUpdate(BaseModel):
    da_lite_status: str  # OK / HOLD / PENDING
    da_lite_remarks: Optional[str] = None
    da_lite_photo_url: Optional[str] = None


class QaChecklistEntry(BaseModel):
    item_id: UUID
    yard_ok: Optional[bool] = None
    yard_remark: Optional[str] = None
    bhagirath_ok: Optional[bool] = None
    bhagirath_remark: Optional[str] = None
    fvi_ok: Optional[bool] = None
    fvi_remark: Optional[str] = None
    fvi_rework_ok: Optional[bool] = None
    fvi_rework_remark: Optional[str] = None
    fvi_rework_pending_ok: Optional[bool] = None
    fvi_rework_pending_remark: Optional[str] = None


class QaChecklistBulkUpdate(BaseModel):
    entries: List[QaChecklistEntry]


class MovementChecklistItemInput(BaseModel):
    item_id: UUID
    is_ok: Optional[bool] = None
    value_text: Optional[str] = None


class MovementLogCreate(BaseModel):
    # in_time is stamped server-side at the moment of "Add Entry" — not typed.
    checkpoint_id: UUID
    responsible_person: Optional[str] = None
    fuel_qty: Optional[Decimal] = None
    remark: Optional[str] = None
    signature_name: Optional[str] = None
    checklist_items: List[MovementChecklistItemInput] = []


class ChassisOut(BaseModel):
    chassis_id: UUID
    chassis_no: str
    model_id: Optional[UUID] = None
    model_name: Optional[str] = None
    fuel_type: str
    fuel_qty_unit: str = 'L'  # L for DIESEL, KG for CNG
    voltage: Optional[str] = None
    yard_location: Optional[str] = None
    transport_id: Optional[str] = None
    dealer_id: Optional[str] = None
    client_id: Optional[str] = None
    source_type: str
    build_order_id: Optional[UUID] = None
    fuel_receiving_qty: Optional[Decimal] = None
    arrival_date: date
    arrival_remark: Optional[str] = None
    da_lite_status: str
    da_lite_checked_at: Optional[datetime] = None
    da_lite_remarks: Optional[str] = None
    da_lite_photo_url: Optional[str] = None
    current_status: str
    tracking_status: str = 'CHASSIS_IN'
    handed_to_production_at: Optional[datetime] = None
    yard_slot_id: Optional[UUID] = None
    remarks: Optional[str] = None
    created_at: datetime

    model_config = {"from_attributes": True, "protected_namespaces": ()}


class TrackingLogOut(BaseModel):
    log_id: UUID
    from_status: Optional[str] = None
    to_status: str
    station_id: Optional[UUID] = None
    station_code: Optional[str] = None
    station_name: Optional[str] = None
    scan_mode: Optional[str] = None
    changed_by_name: Optional[str] = None
    changed_at: datetime
    scan_location: Optional[str] = None
    remarks: Optional[str] = None

    model_config = {"from_attributes": True, "protected_namespaces": ()}


class ChassisTrackingOut(BaseModel):
    found: bool
    chassis_id: Optional[UUID] = None
    chassis_no: str
    model_name: Optional[str] = None
    fuel_type: Optional[str] = None
    arrival_date: Optional[date] = None
    tracking_status: Optional[str] = None
    friendly_status: Optional[str] = None
    current_station_id: Optional[UUID] = None
    current_station_name: Optional[str] = None
    current_station_status: Optional[str] = None  # e.g. "STRUCTURE IN", "PAINT OUT"
    station_state: Optional[str] = None  # "IN" | "OUT" | "NOT_STARTED"
    dwell_minutes: Optional[int] = None
    dwell_formatted: Optional[str] = None
    next_station_name: Optional[str] = None
    station_arrived_at: Optional[datetime] = None
    station_completed_at: Optional[datetime] = None
    timeline: List[TrackingLogOut] = []
    qa_required: bool = False
    qa_cleared: bool = True
    qa_status: Optional[str] = None
    qa_reason: Optional[str] = None
    order_spec: Optional[Dict[str, Any]] = None

    model_config = {"protected_namespaces": ()}


class TrackingScanInput(BaseModel):
    status: str  # WIP / DISPATCHED
    location: Optional[str] = None  # PRODUCTION / DISPATCH
    remarks: Optional[str] = None
    dispatch_photo_url: Optional[str] = None

    model_config = {"protected_namespaces": ()}


class SupervisorScanInput(BaseModel):
    chassis_no: str
    station_id: Optional[UUID] = None
    scan_mode: Optional[str] = "QR_SCAN"  # QR_SCAN / MANUAL
    remarks: Optional[str] = None

    model_config = {"protected_namespaces": ()}


class SupervisorScanResponse(BaseModel):
    action: str  # SCAN_IN | SCAN_OUT
    chassis_id: UUID
    chassis_no: str
    model_name: Optional[str] = None
    station_id: UUID
    station_name: str
    status: str  # e.g. "STRUCTURE IN" or "STRUCTURE OUT"
    elapsed_minutes: Optional[int] = None
    elapsed_display: Optional[str] = None
    next_station_name: Optional[str] = None
    is_final_station: bool = False
    message: str

    model_config = {"protected_namespaces": ()}


class SupervisorStationSummary(BaseModel):
    station_id: UUID
    station_name: str
    station_code: str
    sequence_no: int
    in_count: int
    out_count: int
    total_count: int

    model_config = {"protected_namespaces": ()}


class SupervisorStationChassisItem(BaseModel):
    chassis_id: UUID
    chassis_no: str
    model_name: Optional[str] = None
    fuel_type: Optional[str] = None
    station_state: str  # IN | OUT
    station_status: str  # e.g. "PAINT IN", "PAINT OUT"
    arrived_at: Optional[datetime] = None
    completed_at: Optional[datetime] = None
    elapsed_minutes: Optional[int] = None
    elapsed_display: Optional[str] = None
    da_lite_status: Optional[str] = None
    next_station_name: Optional[str] = None
    server_time: Optional[datetime] = None
    qa_required: bool = False
    qa_cleared: bool = True
    qa_status: Optional[str] = None
    qa_reason: Optional[str] = None

    model_config = {"protected_namespaces": ()}




class QaResultOut(BaseModel):
    result_id: UUID
    item_id: UUID
    yard_ok: Optional[bool] = None
    yard_remark: Optional[str] = None
    bhagirath_ok: Optional[bool] = None
    bhagirath_remark: Optional[str] = None
    fvi_ok: Optional[bool] = None
    fvi_remark: Optional[str] = None
    fvi_rework_ok: Optional[bool] = None
    fvi_rework_remark: Optional[str] = None
    fvi_rework_pending_ok: Optional[bool] = None
    fvi_rework_pending_remark: Optional[str] = None

    model_config = {"from_attributes": True, "protected_namespaces": ()}


class MovementLogOut(BaseModel):
    movement_id: UUID
    checkpoint_id: UUID
    responsible_person: Optional[str] = None
    movement_date: Optional[date] = None
    in_time: Optional[time] = None
    out_time: Optional[time] = None
    fuel_qty: Optional[Decimal] = None
    remark: Optional[str] = None
    signature_name: Optional[str] = None

    model_config = {"from_attributes": True, "protected_namespaces": ()}


class StoreHandoverPartInput(BaseModel):
    part_id: UUID
    status: Optional[str] = None  # OK / NOT_OK / NA
    qty: Optional[int] = None


class StoreHandoverUpdate(BaseModel):
    handover_date: Optional[date] = None
    parts: List[StoreHandoverPartInput] = []


class StoreHandoverPartOut(BaseModel):
    part_id: UUID
    status: Optional[str] = None
    qty: Optional[int] = None

    model_config = {"from_attributes": True, "protected_namespaces": ()}


class StoreHandoverOut(BaseModel):
    handover_id: UUID
    handover_date: Optional[date] = None
    store_manager_approved_by: Optional[UUID] = None
    store_manager_approved_by_name: Optional[str] = None
    store_manager_approved_at: Optional[datetime] = None
    yard_supervisor_approved_by: Optional[UUID] = None
    yard_supervisor_approved_by_name: Optional[str] = None
    yard_supervisor_approved_at: Optional[datetime] = None
    parts: List[StoreHandoverPartOut] = []

    model_config = {"from_attributes": True, "protected_namespaces": ()}


class ChassisDetailOut(BaseModel):
    chassis: ChassisOut
    qa_results: List[QaResultOut]
    movements: List[MovementLogOut]
    store_handover: Optional[StoreHandoverOut] = None
    documents: List['DocumentOut'] = []
    csp: List['CspOut'] = []

    model_config = {"from_attributes": True, "protected_namespaces": ()}


class ChassisQaRemarkOut(BaseModel):
    zone_name: str
    checkpoint_text: str
    remark: Optional[str] = None


class ChassisLookupOut(BaseModel):
    found: bool
    chassis_no: str
    model_number: Optional[str] = None
    da_lite_status: Optional[str] = None
    da_lite_remarks: Optional[str] = None
    da_lite_photo_url: Optional[str] = None
    qa_status: str = 'NOT_FOUND'  # NOT_FOUND / PENDING / OK / REMARKS
    tracking_status: Optional[str] = None
    qa_remarks: List[ChassisQaRemarkOut] = []

    model_config = {"protected_namespaces": ()}


# ── DOCUMENT SCHEMAS ──────────────────────────────────

class DocumentCreate(BaseModel):
    document_type: str  # E_WAY_BILL | INSURANCE | DRIVER_CHALLAN
    document_number: Optional[str] = None
    issue_date: Optional[date] = None
    valid_until: Optional[date] = None
    issuing_authority: Optional[str] = None


class DocumentOut(BaseModel):
    doc_id: UUID
    chassis_id: UUID
    document_type: str
    document_number: Optional[str] = None
    issue_date: Optional[date] = None
    valid_until: Optional[date] = None
    issuing_authority: Optional[str] = None
    file_path: Optional[str] = None
    verification_status: str
    rejection_reason: Optional[str] = None
    verified_at: Optional[datetime] = None
    created_at: datetime

    model_config = {"from_attributes": True, "protected_namespaces": ()}


class DocumentVerify(BaseModel):
    verification_status: str  # VERIFIED | REJECTED
    rejection_reason: Optional[str] = None


# ── CSP SCHEMAS ───────────────────────────────────────

class CspCreate(BaseModel):
    item_description: str
    item_code: Optional[str] = None
    rm_id: Optional[UUID] = None
    quantity_received: Decimal
    unit_of_measurement: Optional[str] = None
    target_station: Optional[str] = None
    storage_location: Optional[str] = None
    notes: Optional[str] = None


class CspOut(BaseModel):
    csp_id: UUID
    chassis_id: UUID
    rm_id: Optional[UUID] = None
    item_description: str
    item_code: Optional[str] = None
    quantity_received: Decimal
    quantity_verified: Optional[Decimal] = None
    unit_of_measurement: Optional[str] = None
    target_station: Optional[str] = None
    storage_location: Optional[str] = None
    status: str
    damaged_qty: Optional[Decimal] = None
    damage_description: Optional[str] = None
    issued_to_station: Optional[str] = None
    issued_at: Optional[datetime] = None
    notes: Optional[str] = None
    created_at: datetime

    model_config = {"from_attributes": True, "protected_namespaces": ()}


class CspStatusUpdate(BaseModel):
    status: str  # VERIFIED | STORED | ISSUED | RETURNED | DAMAGED
    quantity_verified: Optional[Decimal] = None
    storage_location: Optional[str] = None
    issued_to_station: Optional[str] = None
    damaged_qty: Optional[Decimal] = None
    damage_description: Optional[str] = None
    notes: Optional[str] = None


# ── FACTORY LOCATION & STATION MANAGEMENT SCHEMAS ────

class LocationCreate(BaseModel):
    location_code: str
    location_name: str
    sequence_no: Optional[int] = 0
    description: Optional[str] = None
    is_active: Optional[bool] = True


class LocationUpdate(BaseModel):
    location_name: Optional[str] = None
    sequence_no: Optional[int] = None
    description: Optional[str] = None
    is_active: Optional[bool] = None


class StationDetailOut(BaseModel):
    station_id: UUID
    location_id: Optional[UUID] = None
    location_name: Optional[str] = None
    station_code: str
    station_name: str
    sequence_no: Optional[int] = 0
    requires_qa: bool = True
    is_rework_station: bool = False
    is_active: bool = True
    standard_cycle_time_min: Optional[int] = None
    qa_items_count: int = 0

    model_config = {"from_attributes": True, "protected_namespaces": ()}


class LocationOut(BaseModel):
    location_id: UUID
    location_code: str
    location_name: str
    sequence_no: int = 0
    description: Optional[str] = None
    is_active: bool = True
    created_at: Optional[datetime] = None
    stations: List[StationDetailOut] = []

    model_config = {"from_attributes": True, "protected_namespaces": ()}


class StationCreate(BaseModel):
    location_id: Optional[UUID] = None
    station_code: Optional[str] = None
    station_name: str
    sequence_no: Optional[int] = 0
    requires_qa: Optional[bool] = True
    is_rework_station: Optional[bool] = True
    standard_cycle_time_min: Optional[int] = None
    is_active: Optional[bool] = True


class StationUpdate(BaseModel):
    location_id: Optional[UUID] = None
    station_name: Optional[str] = None
    sequence_no: Optional[int] = None
    requires_qa: Optional[bool] = None
    is_rework_station: Optional[bool] = None
    standard_cycle_time_min: Optional[int] = None
    is_active: Optional[bool] = None


class StationQaItemOut(BaseModel):
    item_id: UUID
    station_id: UUID
    zone_name: str
    checkpoint_text: str
    specification: Optional[str] = None
    sequence_no: int = 0
    is_active: bool = True

    model_config = {"from_attributes": True, "protected_namespaces": ()}


class StationQaItemCreate(BaseModel):
    station_id: UUID
    zone_name: Optional[str] = "General"
    checkpoint_text: str
    specification: Optional[str] = None
    sequence_no: Optional[int] = 0
    is_active: Optional[bool] = True
