"""Availability, shifts & working zones DTOs — Phase 10.3."""
from __future__ import annotations

from datetime import datetime
from uuid import UUID

from pydantic import BaseModel, ConfigDict, Field

from app.models.types import (
    DriverAvailabilityStatus,
    ShiftAssignmentStatus,
    ShiftStatus,
    WorkingZoneStatus,
)
from app.schemas.common import ORMBase

_FORBID = ConfigDict(extra="forbid")


class DriverAvailabilityUpsert(BaseModel):
    model_config = _FORBID

    status: DriverAvailabilityStatus
    effective_from: datetime | None = None
    effective_until: datetime | None = None
    notes: str | None = None
    metadata_json: dict | None = None
    version: int | None = Field(default=None, ge=1)


class DriverAvailabilityRead(ORMBase):
    id: UUID
    tenant_id: UUID
    driver_id: UUID
    status: DriverAvailabilityStatus
    effective_from: datetime | None
    effective_until: 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 ShiftCreate(BaseModel):
    model_config = _FORBID

    organization_id: UUID
    hub_id: UUID | None = None
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    status: ShiftStatus = ShiftStatus.DRAFT
    starts_at: datetime
    ends_at: datetime
    metadata_json: dict | None = None


class ShiftUpdate(BaseModel):
    model_config = _FORBID

    hub_id: UUID | None = None
    name: str | None = Field(default=None, max_length=255)
    status: ShiftStatus | None = None
    starts_at: datetime | None = None
    ends_at: datetime | None = None
    metadata_json: dict | None = None
    version: int = Field(ge=1)


class ShiftRead(ORMBase):
    id: UUID
    tenant_id: UUID
    organization_id: UUID
    hub_id: UUID | None
    code: str
    name: str
    status: ShiftStatus
    starts_at: datetime
    ends_at: datetime
    metadata_json: dict | None
    version: int
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class ShiftListResponse(BaseModel):
    items: list[ShiftRead]
    total: int
    page: int
    page_size: int


class ShiftAssignmentCreate(BaseModel):
    model_config = _FORBID

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


class ShiftAssignmentUpdate(BaseModel):
    model_config = _FORBID

    status: ShiftAssignmentStatus | None = None
    notes: str | None = None
    metadata_json: dict | None = None


class ShiftAssignmentRead(ORMBase):
    id: UUID
    tenant_id: UUID
    shift_id: UUID
    driver_id: UUID
    status: ShiftAssignmentStatus
    notes: str | None
    metadata_json: dict | None
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class WorkingZoneCreate(BaseModel):
    model_config = _FORBID

    organization_id: UUID
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    status: WorkingZoneStatus = WorkingZoneStatus.ACTIVE
    geo_boundary_ref: str | None = Field(default=None, max_length=255)
    metadata_json: dict | None = None


class WorkingZoneUpdate(BaseModel):
    model_config = _FORBID

    name: str | None = Field(default=None, max_length=255)
    status: WorkingZoneStatus | None = None
    geo_boundary_ref: str | None = Field(default=None, max_length=255)
    metadata_json: dict | None = None
    version: int = Field(ge=1)


class WorkingZoneRead(ORMBase):
    id: UUID
    tenant_id: UUID
    organization_id: UUID
    code: str
    name: str
    status: WorkingZoneStatus
    geo_boundary_ref: 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 WorkingZoneListResponse(BaseModel):
    items: list[WorkingZoneRead]
    total: int
    page: int
    page_size: int
