"""Delivery integration aggregates — Phase 13.7."""
from __future__ import annotations

import uuid
from datetime import datetime

from sqlalchemy import 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 DeliveryJobStatus, GUID, LifecycleStatus


class DeliveryIntegrationRegistration(
    Base,
    UUIDPrimaryKeyMixin,
    TenantMixin,
    TimestampMixin,
    SoftDeleteMixin,
    ActorAuditMixin,
    OptimisticLockMixin,
):
    __tablename__ = "delivery_integration_registrations"

    clinic_id: Mapped[uuid.UUID | None] = mapped_column(GUID(), nullable=True)
    pharmacy_id: Mapped[uuid.UUID | None] = mapped_column(GUID(), nullable=True)
    code: Mapped[str] = mapped_column(String(50), nullable=False)
    name: Mapped[str] = mapped_column(String(255), nullable=False)
    delivery_merchant_ref: Mapped[str] = mapped_column(String(255), nullable=False)
    webhook_secret_ref: Mapped[str | None] = mapped_column(String(255), nullable=True)
    status: Mapped[LifecycleStatus] = mapped_column(
        default=LifecycleStatus.ACTIVE, nullable=False
    )
    config: Mapped[dict | None] = mapped_column(JSON, nullable=True)

    __table_args__ = (
        UniqueConstraint(
            "tenant_id", "code", name="uq_delivery_integration_registrations_tenant_code"
        ),
        Index("ix_delivery_integration_registrations_tenant", "tenant_id", "status"),
    )


class DeliveryJobIntent(
    Base,
    UUIDPrimaryKeyMixin,
    TenantMixin,
    TimestampMixin,
    SoftDeleteMixin,
    ActorAuditMixin,
    OptimisticLockMixin,
):
    __tablename__ = "delivery_job_intents"

    registration_id: Mapped[uuid.UUID] = mapped_column(GUID(), nullable=False)
    prescription_order_id: Mapped[uuid.UUID] = mapped_column(GUID(), nullable=False)
    code: Mapped[str] = mapped_column(String(50), nullable=False)
    delivery_job_ref: Mapped[str | None] = mapped_column(String(255), nullable=True)
    status: Mapped[DeliveryJobStatus] = mapped_column(
        default=DeliveryJobStatus.QUEUED, nullable=False
    )
    idempotency_key: Mapped[str] = mapped_column(String(100), nullable=False)
    pickup_address: Mapped[dict | None] = mapped_column(JSON, nullable=True)
    dropoff_address: Mapped[dict | None] = mapped_column(JSON, nullable=True)
    metadata_json: Mapped[dict | None] = mapped_column(JSON, nullable=True)

    __table_args__ = (
        UniqueConstraint("tenant_id", "code", name="uq_delivery_job_intents_tenant_code"),
        UniqueConstraint(
            "tenant_id", "idempotency_key", name="uq_delivery_job_intents_idempotency"
        ),
        Index("ix_delivery_job_intents_order", "tenant_id", "prescription_order_id"),
    )


class DeliveryJobStatusSnapshot(Base, UUIDPrimaryKeyMixin, TenantMixin, TimestampMixin):
    __tablename__ = "delivery_job_status_snapshots"

    delivery_job_intent_id: Mapped[uuid.UUID] = mapped_column(GUID(), nullable=False)
    status: Mapped[DeliveryJobStatus] = mapped_column(nullable=False)
    external_status: Mapped[str | None] = mapped_column(String(100), nullable=True)
    recorded_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
    payload: Mapped[dict | None] = mapped_column(JSON, nullable=True)

    __table_args__ = (
        Index(
            "ix_delivery_job_status_snapshots_intent",
            "tenant_id",
            "delivery_job_intent_id",
        ),
    )
