"""Dispatch engine DTOs — Phase 10.5."""
from __future__ import annotations

from datetime import datetime
from uuid import UUID

from pydantic import BaseModel, ConfigDict, Field

from app.models.types import DispatchJobAction, DispatchJobStatus, JobAssignmentStatus
from app.schemas.common import ORMBase

_FORBID = ConfigDict(extra="forbid")


class DispatchJobCreate(BaseModel):
    model_config = _FORBID

    organization_id: UUID
    hub_id: UUID | None = None
    code: str = Field(max_length=50)
    external_order_ref: str | None = Field(default=None, max_length=255)
    external_source: str | None = Field(default=None, max_length=100)
    priority: int = 0
    pickup_address_ref: str | None = Field(default=None, max_length=255)
    dropoff_address_ref: str | None = Field(default=None, max_length=255)
    scheduled_at: datetime | None = None
    metadata_json: dict | None = None


class DispatchJobUpdate(BaseModel):
    model_config = _FORBID

    hub_id: UUID | None = None
    priority: int | None = None
    pickup_address_ref: str | None = Field(default=None, max_length=255)
    dropoff_address_ref: str | None = Field(default=None, max_length=255)
    scheduled_at: datetime | None = None
    metadata_json: dict | None = None
    version: int = Field(ge=1)


class DispatchJobStatusRequest(BaseModel):
    model_config = _FORBID

    action: DispatchJobAction
    reason: str | None = Field(default=None, max_length=500)
    version: int = Field(ge=1)


class DispatchJobRead(ORMBase):
    id: UUID
    tenant_id: UUID
    organization_id: UUID
    hub_id: UUID | None
    code: str
    status: DispatchJobStatus
    external_order_ref: str | None
    external_source: str | None
    priority: int
    pickup_address_ref: str | None
    dropoff_address_ref: str | None
    scheduled_at: datetime | None
    status_reason: str | None
    metadata_json: dict | None
    version: int
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class DispatchJobListResponse(BaseModel):
    items: list[DispatchJobRead]
    total: int
    page: int
    page_size: int


class JobAssignmentCreate(BaseModel):
    model_config = _FORBID

    dispatch_job_id: UUID
    driver_id: UUID
    vehicle_id: UUID | None = None
    notes: str | None = None
    metadata_json: dict | None = None


class JobAssignmentUpdate(BaseModel):
    model_config = _FORBID

    status: JobAssignmentStatus | None = None
    vehicle_id: UUID | None = None
    notes: str | None = None
    metadata_json: dict | None = None
    version: int = Field(ge=1)


class JobAssignmentRead(ORMBase):
    id: UUID
    tenant_id: UUID
    dispatch_job_id: UUID
    driver_id: UUID
    vehicle_id: UUID | None
    status: JobAssignmentStatus
    assigned_at: datetime | None
    notes: str | None
    metadata_json: dict | None
    version: int
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class JobAssignmentListResponse(BaseModel):
    items: list[JobAssignmentRead]
    total: int
    page: int
    page_size: int
