from __future__ import annotations

from sqlalchemy import Boolean, Float, Index, Integer, String, Text, UniqueConstraint
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column


class Base(DeclarativeBase):
    pass


class AuthUser(Base):
    __tablename__ = "auth_users"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    user_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    username: Mapped[str] = mapped_column(String(128), unique=True, index=True)
    password: Mapped[str] = mapped_column(String(256))
    full_name: Mapped[str] = mapped_column(String(256))
    role: Mapped[str] = mapped_column(String(32), index=True)
    created_at: Mapped[str] = mapped_column(String(64))


class AuthExternalIdentity(Base):
    __tablename__ = "auth_external_identities"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    provider: Mapped[str] = mapped_column(String(64), index=True)
    external_subject: Mapped[str] = mapped_column(String(256), index=True)
    username: Mapped[str] = mapped_column(String(128), index=True)
    email: Mapped[str | None] = mapped_column(String(256), nullable=True, index=True)
    full_name: Mapped[str | None] = mapped_column(String(256), nullable=True)
    role: Mapped[str] = mapped_column(String(32), index=True)
    linked_user_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    created_at: Mapped[str] = mapped_column(String(64), index=True)
    updated_at: Mapped[str] = mapped_column(String(64), index=True)
    last_login_at: Mapped[str] = mapped_column(String(64), index=True)


class AuthOIDCState(Base):
    __tablename__ = "auth_oidc_states"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    state: Mapped[str] = mapped_column(String(128), unique=True, index=True)
    nonce: Mapped[str] = mapped_column(String(128))
    code_verifier: Mapped[str] = mapped_column(String(256))
    redirect_uri: Mapped[str] = mapped_column(String(512))
    return_mode: Mapped[str] = mapped_column(String(32), default="popup")
    created_at: Mapped[str] = mapped_column(String(64), index=True)
    expires_at: Mapped[str] = mapped_column(String(64), index=True)
    consumed_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)


class Tenant(Base):
    __tablename__ = "tenants"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    tenant_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    name: Mapped[str] = mapped_column(String(256), index=True)
    business_type: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    industry: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    country: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    city: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    timezone: Mapped[str] = mapped_column(String(64), default="Asia/Almaty")
    language_preferences_json: Mapped[str] = mapped_column(Text, default='["ru"]')
    default_currency: Mapped[str] = mapped_column(String(16), default="KZT", index=True)
    subscription_plan: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    is_active: Mapped[bool] = mapped_column(Boolean, default=True, index=True)
    created_at: Mapped[str] = mapped_column(String(64), index=True)
    updated_at: Mapped[str] = mapped_column(String(64), index=True)


class Customer(Base):
    __tablename__ = "customers"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    customer_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    display_name: Mapped[str] = mapped_column(String(256), index=True)
    phones_json: Mapped[str] = mapped_column(Text, default="[]")
    preferred_phone: Mapped[str | None] = mapped_column(String(64), nullable=True)
    tags_json: Mapped[str] = mapped_column(Text, default="[]")
    created_at: Mapped[str] = mapped_column(String(64))


class CustomerExternalIdentity(Base):
    __tablename__ = "customer_external_identities"
    __table_args__ = (
        Index(
            "ix_customer_external_identities_channel_subject_unique",
            "channel",
            "external_subject",
            unique=True,
        ),
    )

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    identity_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    customer_id: Mapped[str] = mapped_column(String(64), index=True)
    channel: Mapped[str] = mapped_column(String(32), index=True)
    external_subject: Mapped[str] = mapped_column(String(256), index=True)
    display_name_snapshot: Mapped[str | None] = mapped_column(String(256), nullable=True)
    created_at: Mapped[str] = mapped_column(String(64), index=True)
    updated_at: Mapped[str] = mapped_column(String(64), index=True)


class Interaction(Base):
    __tablename__ = "interactions"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    interaction_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    channel: Mapped[str] = mapped_column(String(32), index=True)
    subject: Mapped[str] = mapped_column(String(512))
    customer_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    queue_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    priority: Mapped[int] = mapped_column(Integer, default=3, index=True)
    status: Mapped[str] = mapped_column(String(32), index=True)
    assigned_to: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    created_at: Mapped[str] = mapped_column(String(64))
    updated_at: Mapped[str] = mapped_column(String(64))


class InteractionTimeline(Base):
    __tablename__ = "interaction_timelines"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    interaction_id: Mapped[str] = mapped_column(String(64), index=True)
    timestamp: Mapped[str] = mapped_column(String(64), index=True)
    action: Mapped[str] = mapped_column(String(128))
    metadata_json: Mapped[str] = mapped_column(Text, default="{}")


class Queue(Base):
    __tablename__ = "queues"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    queue_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    name: Mapped[str] = mapped_column(String(256), index=True)
    description: Mapped[str] = mapped_column(Text, default="")
    rules_json: Mapped[str] = mapped_column(Text, default="[]")
    created_at: Mapped[str] = mapped_column(String(64))


class VoiceNameCollectionSettingsRow(Base):
    __tablename__ = "voice_name_collection_settings"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    settings_key: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    config_json: Mapped[str] = mapped_column(Text, default="{}")
    updated_at: Mapped[str] = mapped_column(String(64), index=True)


class VoiceTTSSettingsRow(Base):
    __tablename__ = "voice_tts_settings"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    settings_key: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    config_json: Mapped[str] = mapped_column(Text, default="{}")
    updated_at: Mapped[str] = mapped_column(String(64), index=True)


class AIOperatorSettingsRow(Base):
    __tablename__ = "ai_operator_settings"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    settings_key: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    config_json: Mapped[str] = mapped_column(Text, default="{}")
    updated_at: Mapped[str] = mapped_column(String(64), index=True)


class RoutingCounter(Base):
    __tablename__ = "routing_counters"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    channel: Mapped[str] = mapped_column(String(32), unique=True, index=True)
    counter: Mapped[int] = mapped_column(Integer, default=0)


class AuditEventRow(Base):
    __tablename__ = "audit_events"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    event_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    actor: Mapped[str] = mapped_column(String(128), index=True)
    action: Mapped[str] = mapped_column(String(128), index=True)
    entity: Mapped[str] = mapped_column(String(128), index=True)
    metadata_json: Mapped[str] = mapped_column(Text, default="{}")
    created_at: Mapped[str] = mapped_column(String(64), index=True)


class EventOutboxRow(Base):
    __tablename__ = "event_outbox"
    __table_args__ = (
        Index("idx_event_outbox_status_available_at_id", "status", "available_at", "id"),
    )

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    event_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    event_type: Mapped[str] = mapped_column(String(128), index=True)
    event_version: Mapped[int] = mapped_column(Integer, default=1)
    producer_service: Mapped[str] = mapped_column(String(128), index=True)
    entity_type: Mapped[str] = mapped_column(String(128), index=True)
    entity_id: Mapped[str] = mapped_column(String(128), index=True)
    correlation_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    routing_key: Mapped[str] = mapped_column(String(128), index=True)
    payload_json: Mapped[str] = mapped_column(Text, default="{}")
    status: Mapped[str] = mapped_column(String(32), index=True)
    attempt_count: Mapped[int] = mapped_column(Integer, default=0)
    last_error: Mapped[str | None] = mapped_column(Text, nullable=True)
    available_at: Mapped[str] = mapped_column(String(64), index=True)
    published_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    created_at: Mapped[str] = mapped_column(String(64), index=True)
    updated_at: Mapped[str] = mapped_column(String(64), index=True)


class EventInboxRow(Base):
    __tablename__ = "event_inbox"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    consumer_name: Mapped[str] = mapped_column(String(128), index=True)
    event_id: Mapped[str] = mapped_column(String(64), index=True)
    event_type: Mapped[str] = mapped_column(String(128), index=True)
    processed_at: Mapped[str] = mapped_column(String(64), index=True)
    status: Mapped[str] = mapped_column(String(32), index=True)
    notes: Mapped[str | None] = mapped_column(Text, nullable=True)


class AsteriskEventLogRow(Base):
    __tablename__ = "asterisk_event_log"
    __table_args__ = (
        Index(
            "idx_asterisk_event_log_name_call_status_id",
            "ami_event_name",
            "call_id",
            "forward_status",
            "id",
        ),
    )

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    bridge_event_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    ami_event_name: Mapped[str] = mapped_column(String(128), index=True)
    call_id: Mapped[str] = mapped_column(String(128), index=True)
    linked_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    interaction_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    recording_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    forward_status: Mapped[str] = mapped_column(String(32), index=True)
    payload_json: Mapped[str] = mapped_column(Text, default="{}")
    last_error: Mapped[str | None] = mapped_column(Text, nullable=True)
    created_at: Mapped[str] = mapped_column(String(64), index=True)
    updated_at: Mapped[str] = mapped_column(String(64), index=True)


class AsteriskCallLinkRow(Base):
    __tablename__ = "asterisk_call_links"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    call_id: Mapped[str] = mapped_column(String(128), unique=True, index=True)
    linked_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    queue_code: Mapped[str] = mapped_column(String(64), index=True)
    queue_id: Mapped[str] = mapped_column(String(64), index=True)
    interaction_id: Mapped[str] = mapped_column(String(64), index=True)
    caller_number: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    caller_name: Mapped[str | None] = mapped_column(String(128), nullable=True)
    status: Mapped[str] = mapped_column(String(32), index=True)
    telephony_status: Mapped[str] = mapped_column(String(32), index=True, default="ringing")
    claimed_by_user: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    claimed_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    operator_extension: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    channel_name: Mapped[str | None] = mapped_column(String(256), nullable=True, index=True)
    voice_session_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    ai_session_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    ai_state: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
    ai_handoff_reason: Mapped[str | None] = mapped_column(Text, nullable=True)
    ai_last_model_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    voice_start_language: Mapped[str | None] = mapped_column(String(16), nullable=True, index=True)
    customer_name_status: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
    customer_name_value: Mapped[str | None] = mapped_column(String(256), nullable=True)
    customer_name_source: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
    customer_name_resolved_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    started_at: Mapped[str] = mapped_column(String(64), index=True)
    connected_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    ended_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    updated_at: Mapped[str] = mapped_column(String(64), index=True)
    tenant_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    current_level: Mapped[str | None] = mapped_column(String(16), nullable=True, index=True)
    required_skills_json: Mapped[str] = mapped_column(Text, default="[]")
    priority: Mapped[int] = mapped_column(Integer, default=3)


class AsteriskCallActionLogRow(Base):
    __tablename__ = "asterisk_call_action_log"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    action_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    call_id: Mapped[str] = mapped_column(String(128), index=True)
    interaction_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    action_type: Mapped[str] = mapped_column(String(64), index=True)
    actor_user: Mapped[str] = mapped_column(String(128), index=True)
    actor_role: Mapped[str] = mapped_column(String(32), index=True)
    request_json: Mapped[str] = mapped_column(Text, default="{}")
    result_status: Mapped[str] = mapped_column(String(32), index=True)
    ami_action_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    error: Mapped[str | None] = mapped_column(Text, nullable=True)
    created_at: Mapped[str] = mapped_column(String(64), index=True)


class VoiceEventRow(Base):
    __tablename__ = "voice_events"
    __table_args__ = (
        Index(
            "ix_voice_events_source_event_id",
            "source_event_id",
            unique=True,
        ),
    )

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    event_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    event_type: Mapped[str] = mapped_column(String(64), index=True)
    call_id: Mapped[str] = mapped_column(String(128), index=True)
    interaction_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    source_event_id: Mapped[str | None] = mapped_column(String(64), nullable=True)
    payload_json: Mapped[str] = mapped_column(Text, default="{}")
    created_at: Mapped[str] = mapped_column(String(64), index=True)


class CallRecordingRow(Base):
    __tablename__ = "call_recordings"
    __table_args__ = (
        Index(
            "ix_call_recordings_source_event_id",
            "source_event_id",
            unique=True,
        ),
    )

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    recording_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    channel: Mapped[str] = mapped_column(String(32), index=True)
    call_id: Mapped[str] = mapped_column(String(128), index=True)
    interaction_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    source_event_id: Mapped[str | None] = mapped_column(String(64), nullable=True)
    file_name: Mapped[str] = mapped_column(String(256))
    storage_backend: Mapped[str] = mapped_column(String(32), index=True)
    storage_path: Mapped[str] = mapped_column(Text)
    mime_type: Mapped[str] = mapped_column(String(128))
    size_bytes: Mapped[int] = mapped_column(Integer)
    duration_seconds: Mapped[int | None] = mapped_column(Integer, nullable=True)
    checksum_sha256: Mapped[str] = mapped_column(String(64), index=True)
    status: Mapped[str] = mapped_column(String(32), index=True)
    recorded_at: Mapped[str] = mapped_column(String(64), index=True)
    created_at: Mapped[str] = mapped_column(String(64), index=True)
    updated_at: Mapped[str] = mapped_column(String(64), index=True)
    archived_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)


class IvrFlowRow(Base):
    __tablename__ = "ivr_flows"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    flow_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    name: Mapped[str] = mapped_column(String(256), index=True)
    description: Mapped[str] = mapped_column(Text, default="")
    channel: Mapped[str] = mapped_column(String(32), index=True)
    queue_id: Mapped[str] = mapped_column(String(64), index=True)
    version: Mapped[int] = mapped_column(Integer, default=1)
    is_active: Mapped[bool] = mapped_column(Boolean, default=True, index=True)
    entry_node_id: Mapped[str] = mapped_column(String(64))
    flow_json: Mapped[str] = mapped_column(Text)
    created_at: Mapped[str] = mapped_column(String(64), index=True)
    updated_at: Mapped[str] = mapped_column(String(64), index=True)


class IvrSessionRow(Base):
    __tablename__ = "ivr_sessions"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    session_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    call_id: Mapped[str] = mapped_column(String(128), index=True)
    interaction_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    flow_id: Mapped[str] = mapped_column(String(64), index=True)
    queue_id: Mapped[str] = mapped_column(String(64), index=True)
    current_node_id: Mapped[str] = mapped_column(String(64))
    entered_digits_json: Mapped[str] = mapped_column(Text, default="[]")
    status: Mapped[str] = mapped_column(String(32), index=True)
    outcome_code: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    resolved_queue_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    resolved_queue_code: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    completed_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    created_at: Mapped[str] = mapped_column(String(64), index=True)
    updated_at: Mapped[str] = mapped_column(String(64), index=True)


class AISessionRow(Base):
    __tablename__ = "ai_sessions"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    session_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    channel: Mapped[str] = mapped_column(String(32), index=True)
    call_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    thread_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    interaction_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    customer_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    agent_profile: Mapped[str] = mapped_column(String(64), index=True, default="telegram_support")
    language: Mapped[str | None] = mapped_column(String(16), nullable=True, index=True)
    status: Mapped[str] = mapped_column(String(32), index=True, default="active")
    summary_text: Mapped[str] = mapped_column(Text, default="")
    context_summary_json: Mapped[str] = mapped_column(Text, default="{}")
    context_summary_updated_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    last_user_message_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    last_ai_message_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    handoff_reason: Mapped[str | None] = mapped_column(Text, nullable=True)
    created_at: Mapped[str] = mapped_column(String(64), index=True)
    updated_at: Mapped[str] = mapped_column(String(64), index=True)
    closed_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)


class AIJobRow(Base):
    __tablename__ = "ai_jobs"
    __table_args__ = (
        Index("idx_ai_jobs_thread_status_id", "thread_id", "status", "id"),
        Index("idx_ai_jobs_thread_trigger_id", "thread_id", "trigger_message_id", "id"),
    )

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    job_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    session_id: Mapped[str] = mapped_column(String(64), index=True)
    thread_id: Mapped[str] = mapped_column(String(64), index=True)
    trigger_message_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    status: Mapped[str] = mapped_column(String(32), index=True, default="pending")
    attempts: Mapped[int] = mapped_column(Integer, default=0)
    next_attempt_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    locked_until: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    last_error: Mapped[str | None] = mapped_column(Text, nullable=True)
    created_at: Mapped[str] = mapped_column(String(64), index=True)
    updated_at: Mapped[str] = mapped_column(String(64), index=True)


class VoiceAISessionRow(Base):
    __tablename__ = "voice_ai_sessions"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    session_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    call_id: Mapped[str] = mapped_column(String(128), unique=True, index=True)
    linked_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    interaction_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    customer_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    queue_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    ai_session_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    agent_profile: Mapped[str] = mapped_column(String(64), index=True, default="voice_support")
    language: Mapped[str | None] = mapped_column(String(16), nullable=True, index=True)
    asr_provider: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    tts_provider: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    status: Mapped[str] = mapped_column(String(32), index=True, default="queued")
    handoff_reason: Mapped[str | None] = mapped_column(Text, nullable=True)
    handoff_target_queue_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    voice_start_language: Mapped[str | None] = mapped_column(String(16), nullable=True, index=True)
    customer_name_status: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
    customer_name_value: Mapped[str | None] = mapped_column(String(256), nullable=True)
    customer_name_source: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
    customer_name_resolved_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    media_uuid: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    media_status: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
    media_connected_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    media_ended_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    last_media_frame_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    disclosure_played_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    last_user_utterance_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    last_ai_reply_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    started_at: Mapped[str] = mapped_column(String(64), index=True)
    updated_at: Mapped[str] = mapped_column(String(64), index=True)
    ended_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)


class AITurnRow(Base):
    __tablename__ = "ai_turns"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    turn_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    session_id: Mapped[str] = mapped_column(String(64), index=True)
    thread_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    interaction_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    role: Mapped[str] = mapped_column(String(32), index=True)
    source_type: Mapped[str] = mapped_column(String(32), index=True)
    text: Mapped[str] = mapped_column(Text)
    payload_json: Mapped[str] = mapped_column(Text, default="{}")
    model: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    finish_reason: Mapped[str | None] = mapped_column(String(64), nullable=True)
    latency_ms: Mapped[int | None] = mapped_column(Integer, nullable=True)
    created_at: Mapped[str] = mapped_column(String(64), index=True)


class VoiceTranscriptSegmentRow(Base):
    __tablename__ = "voice_transcript_segments"
    __table_args__ = (
        UniqueConstraint(
            "session_id",
            "sequence_no",
            name="uq_voice_transcript_segments_session_sequence",
        ),
        Index(
            "idx_voice_transcript_segments_session_speaker_final_id",
            "session_id",
            "speaker",
            "is_final",
            "id",
        ),
    )

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    segment_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    session_id: Mapped[str] = mapped_column(String(64), index=True)
    call_id: Mapped[str] = mapped_column(String(128), index=True)
    interaction_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    speaker: Mapped[str] = mapped_column(String(32), index=True)
    source_type: Mapped[str] = mapped_column(String(32), index=True)
    sequence_no: Mapped[int] = mapped_column(Integer, index=True)
    text: Mapped[str] = mapped_column(Text)
    confidence: Mapped[float | None] = mapped_column(Float, nullable=True)
    is_final: Mapped[bool] = mapped_column(Boolean, default=True, index=True)
    barge_in_interrupted: Mapped[bool] = mapped_column(Boolean, default=False, index=True)
    payload_json: Mapped[str] = mapped_column(Text, default="{}")
    created_at: Mapped[str] = mapped_column(String(64), index=True)


class TelegramMessageRow(Base):
    __tablename__ = "telegram_messages"
    __table_args__ = (
        Index(
            "ix_telegram_messages_chat_external_unique",
            "chat_id",
            "telegram_message_id_external",
            unique=True,
        ),
        Index(
            "idx_telegram_messages_thread_direction_author_created_id",
            "thread_id",
            "direction",
            "author_type",
            "created_at",
            "id",
        ),
    )

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    message_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    thread_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    interaction_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    chat_id: Mapped[str] = mapped_column(String(128), index=True)
    text: Mapped[str] = mapped_column(Text)
    customer_external_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    direction: Mapped[str] = mapped_column(String(16), index=True, default="inbound")
    telegram_message_id_external: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    operator_user: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    author_type: Mapped[str] = mapped_column(String(32), index=True, default="customer")
    author_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    delivery_status: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
    delivery_attempts: Mapped[int] = mapped_column(Integer, default=0)
    next_delivery_attempt_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    delivery_locked_until: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    last_delivery_error: Mapped[str | None] = mapped_column(Text, nullable=True)
    payload_json: Mapped[str] = mapped_column(Text, default="{}")
    created_at: Mapped[str] = mapped_column(String(64), index=True)


class TelegramThreadRow(Base):
    __tablename__ = "telegram_threads"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    thread_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    chat_id: Mapped[str] = mapped_column(String(128), unique=True, index=True)
    interaction_id: Mapped[str] = mapped_column(String(64), index=True)
    telegram_user_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    username: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    display_name: Mapped[str | None] = mapped_column(String(256), nullable=True, index=True)
    queue_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    status: Mapped[str] = mapped_column(String(32), index=True)
    claimed_by_user: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    claimed_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    ai_session_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    ai_state: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
    ai_handoff_reason: Mapped[str | None] = mapped_column(Text, nullable=True)
    ai_last_model_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    last_message_at: Mapped[str] = mapped_column(String(64), index=True)
    last_message_preview: Mapped[str] = mapped_column(Text, default="")
    created_at: Mapped[str] = mapped_column(String(64), index=True)
    updated_at: Mapped[str] = mapped_column(String(64), index=True)


class WhatsAppMessageRow(Base):
    __tablename__ = "whatsapp_messages"
    __table_args__ = (
        Index(
            "ix_whatsapp_messages_chat_external_unique",
            "chat_id",
            "whatsapp_message_id_external",
            unique=True,
        ),
        Index(
            "idx_whatsapp_messages_thread_direction_author_created_id",
            "thread_id",
            "direction",
            "author_type",
            "created_at",
            "id",
        ),
    )

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    message_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    thread_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    interaction_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    chat_id: Mapped[str] = mapped_column(String(128), index=True)
    text: Mapped[str] = mapped_column(Text)
    customer_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    direction: Mapped[str] = mapped_column(String(16), index=True, default="inbound")
    whatsapp_message_id_external: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    operator_user: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    author_type: Mapped[str] = mapped_column(String(32), index=True, default="customer")
    author_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    delivery_status: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
    delivery_attempts: Mapped[int] = mapped_column(Integer, default=0)
    next_delivery_attempt_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    delivery_locked_until: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    last_delivery_error: Mapped[str | None] = mapped_column(Text, nullable=True)
    payload_json: Mapped[str] = mapped_column(Text, default="{}")
    created_at: Mapped[str] = mapped_column(String(64), index=True)


class WhatsAppThreadRow(Base):
    __tablename__ = "whatsapp_threads"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    thread_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    chat_id: Mapped[str] = mapped_column(String(128), unique=True, index=True)
    interaction_id: Mapped[str] = mapped_column(String(64), index=True)
    whatsapp_user_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    phone_number: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    display_name: Mapped[str | None] = mapped_column(String(256), nullable=True, index=True)
    queue_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    is_group: Mapped[bool] = mapped_column(Boolean, default=False, index=True)
    status: Mapped[str] = mapped_column(String(32), index=True)
    claimed_by_user: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    claimed_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    ai_session_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    ai_state: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
    ai_handoff_reason: Mapped[str | None] = mapped_column(Text, nullable=True)
    ai_last_model_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    last_message_at: Mapped[str] = mapped_column(String(64), index=True)
    last_message_preview: Mapped[str] = mapped_column(Text, default="")
    created_at: Mapped[str] = mapped_column(String(64), index=True)
    updated_at: Mapped[str] = mapped_column(String(64), index=True)


class WebchatMessageRow(Base):
    __tablename__ = "webchat_messages"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    message_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    session_id: Mapped[str] = mapped_column(String(128), index=True)
    text: Mapped[str] = mapped_column(Text)
    visitor_name: Mapped[str | None] = mapped_column(String(256), nullable=True)
    customer_external_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    interaction_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    queue_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    priority: Mapped[int] = mapped_column(Integer, default=3, index=True)
    payload_json: Mapped[str] = mapped_column(Text, default="{}")
    created_at: Mapped[str] = mapped_column(String(64), index=True)


class EmailMessageRow(Base):
    __tablename__ = "email_messages"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    message_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    from_email: Mapped[str] = mapped_column(String(256), index=True)
    subject: Mapped[str] = mapped_column(String(512), index=True)
    body: Mapped[str] = mapped_column(Text)
    customer_external_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    interaction_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    queue_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    priority: Mapped[int] = mapped_column(Integer, default=3, index=True)
    payload_json: Mapped[str] = mapped_column(Text, default="{}")
    created_at: Mapped[str] = mapped_column(String(64), index=True)


class KBCategoryRow(Base):
    __tablename__ = "kb_categories"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    category_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    name: Mapped[str] = mapped_column(String(256), index=True)
    description: Mapped[str] = mapped_column(Text, default="")
    created_at: Mapped[str] = mapped_column(String(64), index=True)


class KBArticleRow(Base):
    __tablename__ = "kb_articles"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    article_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    category_id: Mapped[str] = mapped_column(String(64), index=True)
    article_group_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    language: Mapped[str] = mapped_column(String(8), index=True, default="ru")
    title: Mapped[str] = mapped_column(String(512), index=True)
    body: Mapped[str] = mapped_column(Text)
    tags_json: Mapped[str] = mapped_column(Text, default="[]")
    created_at: Mapped[str] = mapped_column(String(64), index=True)
    updated_at: Mapped[str] = mapped_column(String(64), index=True)


class ReportingEventRow(Base):
    __tablename__ = "reporting_events"
    __table_args__ = (
        Index("idx_reporting_events_queue_channel_created_at", "queue_id", "channel", "created_at"),
    )

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    queue_id: Mapped[str] = mapped_column(String(64), index=True)
    channel: Mapped[str] = mapped_column(String(32), index=True, default="voice")
    agent_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    answered: Mapped[bool] = mapped_column(Boolean, default=False)
    wait_seconds: Mapped[int] = mapped_column(Integer, default=0)
    handle_seconds: Mapped[int] = mapped_column(Integer, default=0)
    abandoned: Mapped[bool] = mapped_column(Boolean, default=False)
    resolved_first_contact: Mapped[bool] = mapped_column(Boolean, default=False)
    created_at: Mapped[str] = mapped_column(String(64), index=True)


class ReportingEventLogRow(Base):
    __tablename__ = "reporting_event_log"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    event_id: Mapped[str] = mapped_column(String(64), index=True)
    event_type: Mapped[str] = mapped_column(String(128), index=True)
    queue_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    channel: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
    interaction_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    payload_json: Mapped[str] = mapped_column(Text, default="{}")
    created_at: Mapped[str] = mapped_column(String(64), index=True)


class ReportingInteractionFactRow(Base):
    __tablename__ = "reporting_interaction_facts"
    __table_args__ = (
        UniqueConstraint("interaction_id", name="uq_reporting_interaction_facts_interaction_id"),
        Index(
            "idx_reporting_interaction_facts_created_queue_channel",
            "created_at",
            "queue_id",
            "channel",
        ),
        Index(
            "idx_reporting_interaction_facts_status_agent",
            "status",
            "agent_id",
        ),
    )

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    interaction_id: Mapped[str] = mapped_column(String(64), index=True)
    channel: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
    queue_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    agent_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    status: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
    created_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    updated_at: Mapped[str] = mapped_column(String(64), index=True)
    closed_at: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    answered: Mapped[bool | None] = mapped_column(Boolean, nullable=True)
    abandoned: Mapped[bool | None] = mapped_column(Boolean, nullable=True)
    wait_seconds: Mapped[int | None] = mapped_column(Integer, nullable=True)
    handle_seconds: Mapped[int | None] = mapped_column(Integer, nullable=True)
    resolved_first_contact: Mapped[bool | None] = mapped_column(Boolean, nullable=True)
    source: Mapped[str] = mapped_column(String(64), index=True, default="unknown")


class ReportingSavedViewRow(Base):
    __tablename__ = "reporting_saved_views"
    __table_args__ = (
        UniqueConstraint("owner_user", "view_id", name="uq_reporting_saved_views_owner_view"),
        Index("idx_reporting_saved_views_owner_updated", "owner_user", "updated_at"),
    )

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    owner_user: Mapped[str] = mapped_column(String(128), index=True)
    owner_role: Mapped[str | None] = mapped_column(String(32), nullable=True, index=True)
    view_id: Mapped[str] = mapped_column(String(64), index=True)
    name: Mapped[str] = mapped_column(String(160))
    snapshot_json: Mapped[str] = mapped_column(Text, default="{}")
    created_at: Mapped[str] = mapped_column(String(64), index=True)
    updated_at: Mapped[str] = mapped_column(String(64), index=True)


class SupervisorAgentStateRow(Base):
    __tablename__ = "supervisor_agent_states"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    agent_id: Mapped[str] = mapped_column(String(128), unique=True, index=True)
    state: Mapped[str] = mapped_column(String(32), index=True)
    queue_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    updated_at: Mapped[str] = mapped_column(String(64), index=True)


class SupervisorQueueSnapshotRow(Base):
    __tablename__ = "supervisor_queue_snapshots"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    queue_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    in_queue: Mapped[int] = mapped_column(Integer, default=0)
    avg_wait_seconds: Mapped[int] = mapped_column(Integer, default=0)
    updated_at: Mapped[str] = mapped_column(String(64), index=True)


class AgentRow(Base):
    __tablename__ = "agents"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    agent_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    tenant_ids_json: Mapped[str] = mapped_column(Text, default="[]")
    extension: Mapped[str] = mapped_column(String(64), index=True)
    endpoint: Mapped[str | None] = mapped_column(String(128), nullable=True)
    display_name: Mapped[str] = mapped_column(String(256))
    level: Mapped[str] = mapped_column(String(16), index=True)
    skills_json: Mapped[str] = mapped_column(Text, default="[]")
    status: Mapped[str] = mapped_column(String(32), index=True, default="OFFLINE")
    current_call_id: Mapped[str | None] = mapped_column(String(128), nullable=True, index=True)
    max_concurrent_calls: Mapped[int] = mapped_column(Integer, default=1)
    enabled: Mapped[bool] = mapped_column(Boolean, default=True, index=True)
    calls_handled_count: Mapped[int] = mapped_column(Integer, default=0)
    created_at: Mapped[str] = mapped_column(String(64))
    updated_at: Mapped[str] = mapped_column(String(64), index=True)


class EscalationRow(Base):
    __tablename__ = "escalations"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    escalation_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    call_id: Mapped[str] = mapped_column(String(128), index=True)
    tenant_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    from_level: Mapped[str] = mapped_column(String(16), index=True)
    to_level: Mapped[str] = mapped_column(String(16), index=True)
    reason_code: Mapped[str] = mapped_column(String(64), index=True)
    required_skills_json: Mapped[str] = mapped_column(Text, default="[]")
    priority: Mapped[int] = mapped_column(Integer, default=3)
    topic: Mapped[str | None] = mapped_column(String(256), nullable=True)
    summary: Mapped[str | None] = mapped_column(Text, nullable=True)
    status: Mapped[str] = mapped_column(String(32), index=True, default="requested")
    assigned_agent_id: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    requested_at: Mapped[str] = mapped_column(String(64), index=True)
    connected_at: Mapped[str | None] = mapped_column(String(64), nullable=True)
    completed_at: Mapped[str | None] = mapped_column(String(64), nullable=True)

    __table_args__ = (
        Index(
            "idx_escalations_call_id_status",
            "call_id",
            "status",
        ),
    )


class RoutingRuleRow(Base):
    __tablename__ = "routing_rules"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    rule_id: Mapped[str] = mapped_column(String(64), unique=True, index=True)
    from_level: Mapped[str] = mapped_column(String(16), index=True)
    to_level: Mapped[str] = mapped_column(String(16), index=True)
    reason_code: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    enabled: Mapped[bool] = mapped_column(Boolean, default=True, index=True)
    priority: Mapped[int] = mapped_column(Integer, default=3)
    created_at: Mapped[str] = mapped_column(String(64))
    updated_at: Mapped[str] = mapped_column(String(64))
