"""Driver management aggregates — Phase 10.1.

UUID refs only within delivery_db. No fleet/dispatch ownership.
Identity/CRM/Storage are external refs only.
"""
from __future__ import annotations

import uuid
from datetime import date, datetime

from sqlalchemy import (
    Boolean,
    Date,
    DateTime,
    Index,
    String,
    Text,
    UniqueConstraint,
)
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy.types import JSON

from app.core.database import Base
from app.models.base import (
    ActorAuditMixin,
    OptimisticLockMixin,
    SoftDeleteMixin,
    TenantMixin,
    TimestampMixin,
    UUIDPrimaryKeyMixin,
)
from app.models.types import (
    DriverCredentialKind,
    DriverDocumentKind,
    DriverLifecycleAction,
    DriverStatus,
    GUID,
)


class Driver(
    Base,
    UUIDPrimaryKeyMixin,
    TenantMixin,
    TimestampMixin,
    SoftDeleteMixin,
    ActorAuditMixin,
    OptimisticLockMixin,
):
    """Courier/driver profile owned by Delivery Platform."""

    __tablename__ = "drivers"

    organization_id: Mapped[uuid.UUID] = mapped_column(GUID(), nullable=False)
    hub_id: Mapped[uuid.UUID | None] = mapped_column(GUID(), nullable=True)
    code: Mapped[str] = mapped_column(String(50), nullable=False)
    display_name: Mapped[str] = mapped_column(String(255), nullable=False)
    first_name: Mapped[str | None] = mapped_column(String(100), nullable=True)
    last_name: Mapped[str | None] = mapped_column(String(100), nullable=True)
    mobile: Mapped[str | None] = mapped_column(String(32), nullable=True)
    email: Mapped[str | None] = mapped_column(String(255), nullable=True)
    status: Mapped[DriverStatus] = mapped_column(
        default=DriverStatus.PENDING, nullable=False
    )
    external_user_ref: Mapped[str | None] = mapped_column(String(100), nullable=True)
    external_crm_contact_ref: Mapped[str | None] = mapped_column(
        String(100), nullable=True
    )
    hire_date: Mapped[date | None] = mapped_column(Date, nullable=True)
    notes: Mapped[str | None] = mapped_column(Text, nullable=True)
    capability_tags: Mapped[list | None] = mapped_column(JSON, nullable=True)
    metadata_json: Mapped[dict | None] = mapped_column(JSON, nullable=True)
    status_reason: Mapped[str | None] = mapped_column(String(500), nullable=True)
    status_changed_at: Mapped[datetime | None] = mapped_column(
        DateTime(timezone=True), nullable=True
    )

    __table_args__ = (
        UniqueConstraint("tenant_id", "code", name="uq_drivers_tenant_code"),
        Index("ix_drivers_tenant_status", "tenant_id", "status"),
        Index("ix_drivers_org", "tenant_id", "organization_id"),
        Index("ix_drivers_hub", "tenant_id", "hub_id"),
        Index("ix_drivers_mobile", "tenant_id", "mobile"),
        Index("ix_drivers_tenant_deleted", "tenant_id", "is_deleted"),
        Index("ix_drivers_display_name", "tenant_id", "display_name"),
    )


class DriverCredential(
    Base,
    UUIDPrimaryKeyMixin,
    TenantMixin,
    TimestampMixin,
    SoftDeleteMixin,
    ActorAuditMixin,
):
    """Credential / compliance refs for a driver (binaries via Storage refs)."""

    __tablename__ = "driver_credentials"

    driver_id: Mapped[uuid.UUID] = mapped_column(GUID(), nullable=False)
    kind: Mapped[DriverCredentialKind] = mapped_column(
        default=DriverCredentialKind.LICENSE, nullable=False
    )
    number: Mapped[str] = mapped_column(String(100), nullable=False)
    issued_at: Mapped[date | None] = mapped_column(Date, nullable=True)
    expires_at: Mapped[date | None] = mapped_column(Date, nullable=True)
    is_verified: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False)
    document_file_ref: Mapped[str | None] = mapped_column(String(255), nullable=True)
    metadata_json: Mapped[dict | None] = mapped_column(JSON, nullable=True)

    __table_args__ = (
        UniqueConstraint(
            "tenant_id",
            "driver_id",
            "kind",
            "number",
            name="uq_driver_credentials_tenant_kind_number",
        ),
        Index("ix_driver_credentials_driver", "tenant_id", "driver_id"),
        Index("ix_driver_credentials_tenant_deleted", "tenant_id", "is_deleted"),
    )


class DriverDocument(
    Base,
    UUIDPrimaryKeyMixin,
    TenantMixin,
    TimestampMixin,
    SoftDeleteMixin,
    ActorAuditMixin,
):
    """Driver document metadata — Storage owns file blobs."""

    __tablename__ = "driver_documents"

    driver_id: Mapped[uuid.UUID] = mapped_column(GUID(), nullable=False)
    kind: Mapped[DriverDocumentKind] = mapped_column(
        default=DriverDocumentKind.OTHER, nullable=False
    )
    title: Mapped[str] = mapped_column(String(255), nullable=False)
    storage_file_ref: Mapped[str] = mapped_column(String(255), nullable=False)
    notes: Mapped[str | None] = mapped_column(Text, nullable=True)

    __table_args__ = (
        Index("ix_driver_documents_driver", "tenant_id", "driver_id"),
        Index("ix_driver_documents_tenant_deleted", "tenant_id", "is_deleted"),
    )


class DriverLifecycleEvent(Base, UUIDPrimaryKeyMixin, TenantMixin, TimestampMixin):
    """Append-only driver lifecycle history."""

    __tablename__ = "driver_lifecycle_events"

    driver_id: Mapped[uuid.UUID] = mapped_column(GUID(), nullable=False)
    action: Mapped[DriverLifecycleAction] = mapped_column(nullable=False)
    from_status: Mapped[DriverStatus] = mapped_column(nullable=False)
    to_status: Mapped[DriverStatus] = mapped_column(nullable=False)
    reason: Mapped[str | None] = mapped_column(String(500), nullable=True)
    actor_user_id: Mapped[str | None] = mapped_column(String(100), nullable=True)
    metadata_json: Mapped[dict | None] = mapped_column(JSON, nullable=True)

    __table_args__ = (
        Index("ix_driver_lifecycle_driver", "tenant_id", "driver_id"),
        Index("ix_driver_lifecycle_created", "tenant_id", "created_at"),
    )
