"""Delivery foundation DTOs — Phase 10.0."""
from __future__ import annotations

from datetime import datetime
from uuid import UUID

from pydantic import BaseModel, ConfigDict, Field

from app.models.types import (
    LifecycleStatus,
    ProviderKind,
    ProviderStatus,
    RoutingEngineStatus,
)
from app.schemas.common import ORMBase

_FORBID = ConfigDict(extra="forbid")


class DeliveryOrganizationCreate(BaseModel):
    model_config = _FORBID

    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    description: str | None = None
    status: LifecycleStatus = LifecycleStatus.DRAFT
    legal_name: str | None = Field(default=None, max_length=255)
    timezone: str = Field(default="Asia/Tehran", max_length=64)
    language: str = Field(default="fa", max_length=16)
    currency_code: str = Field(default="IRR", max_length=3)
    settings: dict | None = None


class DeliveryOrganizationUpdate(BaseModel):
    model_config = _FORBID

    name: str | None = Field(default=None, max_length=255)
    description: str | None = None
    status: LifecycleStatus | None = None
    legal_name: str | None = Field(default=None, max_length=255)
    timezone: str | None = Field(default=None, max_length=64)
    language: str | None = Field(default=None, max_length=16)
    currency_code: str | None = Field(default=None, max_length=3)
    settings: dict | None = None
    version: int = Field(ge=1)


class DeliveryOrganizationRead(ORMBase):
    id: UUID
    tenant_id: UUID
    code: str
    name: str
    description: str | None
    status: LifecycleStatus
    legal_name: str | None
    timezone: str
    language: str
    currency_code: str
    settings: dict | None
    version: int
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class DeliveryHubCreate(BaseModel):
    model_config = _FORBID

    organization_id: UUID
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    description: str | None = None
    status: LifecycleStatus = LifecycleStatus.ACTIVE
    address: dict | None = None
    timezone: str | None = Field(default=None, max_length=64)
    working_hours: dict | None = None
    metadata_json: dict | None = None


class DeliveryHubUpdate(BaseModel):
    model_config = _FORBID

    name: str | None = Field(default=None, max_length=255)
    description: str | None = None
    status: LifecycleStatus | None = None
    address: dict | None = None
    timezone: str | None = Field(default=None, max_length=64)
    working_hours: dict | None = None
    metadata_json: dict | None = None


class DeliveryHubRead(ORMBase):
    id: UUID
    tenant_id: UUID
    organization_id: UUID
    code: str
    name: str
    description: str | None
    status: LifecycleStatus
    address: dict | None
    timezone: str | None
    working_hours: dict | None
    metadata_json: dict | None
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class ExternalProviderConfigCreate(BaseModel):
    model_config = _FORBID

    organization_id: UUID | None = None
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    provider_kind: ProviderKind = ProviderKind.CUSTOM
    adapter_key: str = Field(max_length=100)
    status: ProviderStatus = ProviderStatus.REGISTERED
    priority: int = Field(default=100, ge=0)
    credentials_ref: str | None = Field(default=None, max_length=255)
    config: dict | None = None
    capabilities: dict | None = None


class ExternalProviderConfigUpdate(BaseModel):
    model_config = _FORBID

    name: str | None = Field(default=None, max_length=255)
    provider_kind: ProviderKind | None = None
    adapter_key: str | None = Field(default=None, max_length=100)
    status: ProviderStatus | None = None
    priority: int | None = Field(default=None, ge=0)
    credentials_ref: str | None = Field(default=None, max_length=255)
    config: dict | None = None
    capabilities: dict | None = None
    version: int = Field(ge=1)


class ExternalProviderConfigRead(ORMBase):
    id: UUID
    tenant_id: UUID
    organization_id: UUID | None
    code: str
    name: str
    provider_kind: ProviderKind
    adapter_key: str
    status: ProviderStatus
    priority: int
    credentials_ref: str | None
    config: dict | None
    capabilities: dict | None
    version: int
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class RoutingEngineRegistrationCreate(BaseModel):
    model_config = _FORBID

    organization_id: UUID | None = None
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    adapter_key: str = Field(max_length=100)
    status: RoutingEngineStatus = RoutingEngineStatus.REGISTERED
    is_default: bool = False
    config: dict | None = None
    capabilities: dict | None = None


class RoutingEngineRegistrationUpdate(BaseModel):
    model_config = _FORBID

    name: str | None = Field(default=None, max_length=255)
    adapter_key: str | None = Field(default=None, max_length=100)
    status: RoutingEngineStatus | None = None
    is_default: bool | None = None
    config: dict | None = None
    capabilities: dict | None = None
    version: int = Field(ge=1)


class RoutingEngineRegistrationRead(ORMBase):
    id: UUID
    tenant_id: UUID
    organization_id: UUID | None
    code: str
    name: str
    adapter_key: str
    status: RoutingEngineStatus
    is_default: bool
    config: dict | None
    capabilities: dict | None
    version: int
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class DeliveryConfigurationCreate(BaseModel):
    model_config = _FORBID

    organization_id: UUID
    hub_id: UUID | None = None
    code: str = Field(max_length=50)
    working_hours: dict | None = None
    dispatch_policies: dict | None = None
    tracking_policies: dict | None = None
    settlement_policies: dict | None = None
    custom_fields: dict | None = None
    timezone: str = Field(default="Asia/Tehran", max_length=64)
    language: str = Field(default="fa", max_length=16)
    currency_code: str = Field(default="IRR", max_length=3)


class DeliveryConfigurationUpdate(BaseModel):
    model_config = _FORBID

    hub_id: UUID | None = None
    working_hours: dict | None = None
    dispatch_policies: dict | None = None
    tracking_policies: dict | None = None
    settlement_policies: dict | None = None
    custom_fields: dict | None = None
    timezone: str | None = Field(default=None, max_length=64)
    language: str | None = Field(default=None, max_length=16)
    currency_code: str | None = Field(default=None, max_length=3)
    version: int = Field(ge=1)


class DeliveryConfigurationRead(ORMBase):
    id: UUID
    tenant_id: UUID
    organization_id: UUID
    hub_id: UUID | None
    code: str
    working_hours: dict | None
    dispatch_policies: dict | None
    tracking_policies: dict | None
    settlement_policies: dict | None
    custom_fields: dict | None
    timezone: str
    language: str
    currency_code: str
    version: int
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class DeliverySettingUpsert(BaseModel):
    model_config = _FORBID

    organization_id: UUID | None = None
    hub_id: UUID | None = None
    key: str = Field(max_length=100)
    value: dict | None = None
    description: str | None = None


class DeliverySettingRead(ORMBase):
    id: UUID
    tenant_id: UUID
    organization_id: UUID | None
    hub_id: UUID | None
    key: str
    value: dict | None
    description: str | None
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class DeliveryAuditLogRead(ORMBase):
    id: UUID
    tenant_id: UUID
    entity_type: str
    entity_id: UUID
    action: str
    actor_user_id: str | None
    changes: dict | None
    message: str | None
    created_at: datetime
