"""Tracking & proof of delivery DTOs — Phase 10.7."""
from __future__ import annotations

from datetime import datetime
from uuid import UUID

from pydantic import BaseModel, ConfigDict, Field

from app.models.types import (
    CustomerTrackingTokenStatus,
    ProofOfDeliveryStatus,
    TrackingSessionStatus,
)
from app.schemas.common import ORMBase

_FORBID = ConfigDict(extra="forbid")


class TrackingSessionCreate(BaseModel):
    model_config = _FORBID

    dispatch_job_id: UUID | None = None
    driver_id: UUID | None = None
    metadata_json: dict | None = None


class TrackingSessionUpdate(BaseModel):
    model_config = _FORBID

    status: TrackingSessionStatus | None = None
    metadata_json: dict | None = None
    version: int = Field(ge=1)


class TrackingSessionRead(ORMBase):
    id: UUID
    tenant_id: UUID
    dispatch_job_id: UUID | None
    driver_id: UUID | None
    status: TrackingSessionStatus
    started_at: datetime | None
    ended_at: datetime | 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 TrackingSessionListResponse(BaseModel):
    items: list[TrackingSessionRead]
    total: int
    page: int
    page_size: int


class TrackingPointCreate(BaseModel):
    model_config = _FORBID

    latitude: float = Field(ge=-90, le=90)
    longitude: float = Field(ge=-180, le=180)
    recorded_at: datetime
    metadata_json: dict | None = None


class TrackingPointRead(ORMBase):
    id: UUID
    tenant_id: UUID
    tracking_session_id: UUID
    latitude: float
    longitude: float
    recorded_at: datetime
    metadata_json: dict | None
    created_at: datetime
    updated_at: datetime


class ProofOfDeliveryCreate(BaseModel):
    model_config = _FORBID

    dispatch_job_id: UUID
    signature_file_ref: str | None = Field(default=None, max_length=255)
    photo_file_ref: str | None = Field(default=None, max_length=255)
    delivery_code: str | None = Field(default=None, max_length=50)
    notes: str | None = None
    metadata_json: dict | None = None


class ProofOfDeliveryUpdate(BaseModel):
    model_config = _FORBID

    status: ProofOfDeliveryStatus | None = None
    signature_file_ref: str | None = Field(default=None, max_length=255)
    photo_file_ref: str | None = Field(default=None, max_length=255)
    delivery_code: str | None = Field(default=None, max_length=50)
    notes: str | None = None
    metadata_json: dict | None = None
    version: int = Field(ge=1)


class ProofOfDeliveryRead(ORMBase):
    id: UUID
    tenant_id: UUID
    dispatch_job_id: UUID
    status: ProofOfDeliveryStatus
    signature_file_ref: str | None
    photo_file_ref: str | None
    delivery_code: str | None
    notes: str | None
    captured_at: datetime | 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 ProofOfDeliveryListResponse(BaseModel):
    items: list[ProofOfDeliveryRead]
    total: int
    page: int
    page_size: int


class CustomerTrackingTokenCreate(BaseModel):
    model_config = _FORBID

    dispatch_job_id: UUID
    expires_at: datetime | None = None
    metadata_json: dict | None = None


class CustomerTrackingTokenRead(ORMBase):
    id: UUID
    tenant_id: UUID
    dispatch_job_id: UUID
    token: str
    status: CustomerTrackingTokenStatus
    expires_at: datetime | None
    metadata_json: dict | None
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class CustomerTrackingTokenListResponse(BaseModel):
    items: list[CustomerTrackingTokenRead]
    total: int
    page: int
    page_size: int
