from __future__ import annotations

from typing import Literal

from pydantic import BaseModel, Field


SalesLeadTemperature = Literal["warm", "hot"]
SalesChannelType = Literal["text", "voice"]
SalesPreferredChannel = Literal["telegram", "whatsapp", "webchat", "email", "voice"]
SalesDirection = Literal["inbound", "outbound"]
SalesAgentType = Literal["text_ai", "voice_ai", "human"]
SalesLeadStatus = Literal["new_qualified_lead", "warm_lead", "hot_lead", "enrichment_required", "converted", "lost"]
SalesDealStatus = Literal["active", "won", "lost", "postponed", "closed"]
SalesScenarioType = Literal[
    "quick_sale",
    "consultative_sale",
    "quotation_based_sale",
    "booking_based_sale",
    "subscription_sale",
    "custom_human_escalation",
]
SalesOfferType = Literal["offer", "quotation", "estimate", "order", "booking", "appointment", "subscription_plan"]
SalesOfferStatus = Literal["draft", "sent", "viewed", "accepted", "rejected"]
SalesTranscriptStatus = Literal["pending", "ready"]
SalesDocumentType = Literal[
    "contract",
    "offer_acceptance",
    "appendix",
    "specification",
    "invoice_basis_doc",
    "order_confirmation",
    "booking_confirmation",
    "appointment_confirmation",
    "additional_agreement",
]
SalesDocumentStatus = Literal["draft", "sent", "under_review", "confirmed", "signed"]
SalesInvoiceStatus = Literal["draft", "issued", "sent", "partially_paid", "paid", "overdue", "canceled"]
SalesPaymentStatus = Literal["pending", "success", "failed", "canceled", "partial"]
SalesEscalationSeverity = Literal["low", "medium", "high", "critical"]
SalesEscalationStatus = Literal["open", "assigned", "in_progress", "resolved", "canceled"]
SalesAutomationStatus = Literal["pending", "running", "completed", "failed", "canceled"]
SalesPipelineStageCategory = Literal["entry", "communication", "commercial", "paperwork", "finance", "closing"]
SalesSwitchChannel = Literal["text", "voice"]


class SalesStageRefOut(BaseModel):
    id: str
    code: str
    name: str
    category: SalesPipelineStageCategory
    sort_order: int


class SalesPipelineOut(BaseModel):
    pipeline_id: str
    tenant_id: str
    code: str
    name: str
    description: str | None = None
    is_default: bool
    is_active: bool
    created_at: str
    updated_at: str


class SalesPipelineCreate(BaseModel):
    code: str = Field(default="default_sales", min_length=2)
    name: str = Field(min_length=2)
    description: str | None = None
    is_default: bool = False
    is_active: bool = True


class SalesPipelineUpdate(BaseModel):
    name: str | None = Field(default=None, min_length=2)
    description: str | None = None
    is_default: bool | None = None
    is_active: bool | None = None


class SalesPipelineStageOut(BaseModel):
    stage_id: str
    tenant_id: str
    pipeline_id: str
    code: str
    name: str
    category: SalesPipelineStageCategory
    sort_order: int
    is_terminal: bool
    is_system: bool
    is_active: bool
    created_at: str
    updated_at: str


class SalesPipelineStageCreate(BaseModel):
    code: str = Field(min_length=2)
    name: str = Field(min_length=2)
    category: SalesPipelineStageCategory
    sort_order: int = 0
    is_terminal: bool = False
    is_system: bool = False
    is_active: bool = True


class SalesPipelineStageUpdate(BaseModel):
    name: str | None = Field(default=None, min_length=2)
    category: SalesPipelineStageCategory | None = None
    sort_order: int | None = None
    is_active: bool | None = None


class SalesLeadCreate(BaseModel):
    source_type: str = Field(default="crm")
    source_channel: str = Field(default="webchat")
    source_campaign_id: str | None = None
    full_name: str = Field(min_length=2)
    company_name: str | None = None
    phone: str | None = None
    email: str | None = None
    messenger_handles: dict = Field(default_factory=dict)
    lead_temperature: SalesLeadTemperature = "warm"
    lead_score: float = Field(default=50.0, ge=0, le=100)
    customer_type: str | None = None
    segment_type: str | None = None
    initial_need_summary: str | None = None
    preferred_channel: SalesPreferredChannel = "telegram"
    assigned_agent_type: SalesAgentType = "text_ai"
    status: SalesLeadStatus = "new_qualified_lead"
    priority: int = Field(default=3, ge=1, le=5)
    title: str | None = None
    estimated_amount: float | None = Field(default=None, ge=0)
    currency: str = "KZT"


class SalesLeadUpdate(BaseModel):
    full_name: str | None = Field(default=None, min_length=2)
    company_name: str | None = None
    phone: str | None = None
    email: str | None = None
    messenger_handles: dict | None = None
    lead_temperature: SalesLeadTemperature | None = None
    lead_score: float | None = Field(default=None, ge=0, le=100)
    customer_type: str | None = None
    segment_type: str | None = None
    initial_need_summary: str | None = None
    preferred_channel: SalesPreferredChannel | None = None
    assigned_agent_type: SalesAgentType | None = None
    status: SalesLeadStatus | None = None


class SalesLeadEnrichIn(BaseModel):
    need_summary: str | None = None
    product_context: dict = Field(default_factory=dict)
    customer_type: str | None = None
    preferred_channel: SalesPreferredChannel | None = None
    scenario_type: SalesScenarioType | None = None
    required_fields: dict = Field(default_factory=dict)


class SalesLeadOut(BaseModel):
    lead_id: str
    tenant_id: str
    deal_id: str | None = None
    source_type: str
    source_channel: str
    source_campaign_id: str | None = None
    full_name: str
    company_name: str | None = None
    phone: str | None = None
    email: str | None = None
    messenger_handles: dict = Field(default_factory=dict)
    lead_temperature: SalesLeadTemperature
    lead_score: float
    customer_type: str | None = None
    segment_type: str | None = None
    initial_need_summary: str | None = None
    preferred_channel: SalesPreferredChannel
    assigned_agent_type: SalesAgentType
    status: SalesLeadStatus
    crm_customer_id: str | None = None
    created_at: str
    updated_at: str


class SalesCustomerOut(BaseModel):
    customer_id: str
    display_name: str
    phones: list = Field(default_factory=list)
    preferred_phone: str | None = None
    tags: list = Field(default_factory=list)
    deal_count: int = 0
    created_at: str


class SalesCustomerUpdate(BaseModel):
    display_name: str | None = Field(default=None, min_length=2)
    phones: list | None = None
    preferred_phone: str | None = None
    tags: list | None = None


class SalesDealCreate(BaseModel):
    lead_id: str | None = None
    customer_id: str | None = None
    stage_id: str | None = Field(default=None, min_length=2)
    stage_code: str | None = Field(default=None, min_length=2)
    scenario_type: SalesScenarioType = "quick_sale"
    priority: int = Field(default=3, ge=1, le=5)
    title: str = Field(min_length=3)
    need_summary: str | None = None
    product_context: dict = Field(default_factory=dict)
    estimated_amount: float | None = Field(default=None, ge=0)
    final_amount: float | None = Field(default=None, ge=0)
    currency: str = "KZT"
    payment_model: str | None = None
    document_required: bool = True
    payment_required: bool = True
    preferred_channel: SalesPreferredChannel = "telegram"
    current_channel: SalesPreferredChannel = "telegram"


class SalesDealUpdate(BaseModel):
    title: str | None = Field(default=None, min_length=3)
    need_summary: str | None = None
    product_context: dict | None = None
    estimated_amount: float | None = Field(default=None, ge=0)
    final_amount: float | None = Field(default=None, ge=0)
    currency: str | None = None
    payment_model: str | None = None
    document_required: bool | None = None
    payment_required: bool | None = None
    preferred_channel: SalesPreferredChannel | None = None
    current_channel: SalesPreferredChannel | None = None
    assigned_human_user_id: str | None = None
    next_action_type: str | None = None
    next_action_at: str | None = None


class SalesDealStageChangeIn(BaseModel):
    stage_id: str | None = Field(default=None, min_length=2)
    stage_code: str | None = Field(default=None, min_length=2)
    target_stage_id: str | None = Field(default=None, min_length=2)
    target_stage_code: str | None = Field(default=None, min_length=2)
    reason: str | None = None
    metadata: dict = Field(default_factory=dict)
    force: bool = False


class SalesDealScenarioIn(BaseModel):
    scenario_type: SalesScenarioType


class SalesDealNextActionIn(BaseModel):
    next_action_type: str = Field(min_length=2)
    next_action_at: str | None = None
    payload: dict = Field(default_factory=dict)


class SalesDealCloseIn(BaseModel):
    status: Literal["won", "lost", "postponed"]
    reason: str | None = None


class SalesDealOut(BaseModel):
    deal_id: str
    tenant_id: str
    lead_id: str | None = None
    customer_id: str | None = None
    pipeline_id: str
    stage_id: str
    pipeline: SalesPipelineOut | None = None
    stage: SalesStageRefOut | None = None
    scenario_type: SalesScenarioType
    priority: int
    title: str
    need_summary: str | None = None
    product_context: dict = Field(default_factory=dict)
    estimated_amount: float | None = None
    final_amount: float | None = None
    currency: str
    payment_model: str | None = None
    document_required: bool = True
    payment_required: bool = True
    assigned_human_user_id: str | None = None
    assigned_ai_orchestrator_id: str | None = None
    preferred_channel: str
    current_channel: str
    status: SalesDealStatus
    won_reason: str | None = None
    lost_reason: str | None = None
    close_reason: str | None = None
    next_action_type: str | None = None
    next_action_at: str | None = None
    last_contact_at: str | None = None
    closed_at: str | None = None
    created_at: str
    updated_at: str


class SalesCommunicationStartIn(BaseModel):
    channel_type: SalesChannelType
    direction: SalesDirection = "outbound"
    agent_type: SalesAgentType | None = None
    subject: str | None = None
    summary: str | None = None
    next_action_type: str | None = None
    next_action_at: str | None = None


class SalesCommunicationSummaryIn(BaseModel):
    summary: str = Field(min_length=2)
    result_code: str | None = None
    sentiment: str | None = None
    next_action_type: str | None = None
    next_action_at: str | None = None


class SalesCommunicationSwitchChannelIn(BaseModel):
    to_channel: SalesSwitchChannel
    reason_code: str = "human_decision"
    reason_text: str | None = None
    reason_for_channel_switch: str | None = None
    create_session: bool = False
    scheduled_at: str | None = None
    metadata: dict = Field(default_factory=dict)
    source_type: str | None = None
    source_id: str | None = None
    recommended_by_task_id: str | None = None


class SalesCommunicationBindExternalIn(BaseModel):
    channel_provider: str | None = None
    telegram_thread_id: str | None = None
    telegram_chat_id: str | None = None
    voice_session_id: str | None = None
    external_call_id: str | None = None
    metadata: dict = Field(default_factory=dict)


class SalesCommunicationOut(BaseModel):
    communication_id: str
    tenant_id: str
    deal_id: str
    lead_id: str | None = None
    customer_id: str | None = None
    channel_type: SalesChannelType
    channel_provider: str | None = None
    direction: SalesDirection
    agent_type: SalesAgentType
    started_at: str
    ended_at: str | None = None
    duration_sec: int | None = None
    subject: str | None = None
    status: str
    summary: str | None = None
    transcript_id: str | None = None
    next_action_type: str | None = None
    next_action_at: str | None = None
    sentiment: str | None = None
    result_code: str | None = None
    metadata: dict = Field(default_factory=dict)
    created_at: str
    updated_at: str


class SalesMessageWebhookIn(BaseModel):
    deal_id: str | None = None
    lead_id: str | None = None
    phone: str | None = None
    channel_provider: str = "telegram"
    external_message_id: str | None = None
    sender_id: str | None = None
    body: str = Field(min_length=1)
    attachments: list[dict] = Field(default_factory=list)
    metadata: dict = Field(default_factory=dict)


class SalesMessageSendIn(BaseModel):
    deal_id: str
    communication_id: str | None = None
    channel_provider: str = "telegram"
    sender_type: Literal["text_ai", "human"] = "text_ai"
    sender_id: str | None = None
    body: str = Field(min_length=1)
    attachments: list[dict] = Field(default_factory=list)
    metadata: dict = Field(default_factory=dict)


class SalesMessageOut(BaseModel):
    message_id: str
    deal_id: str
    communication_id: str
    sender_type: str
    sender_id: str | None = None
    channel_provider: str
    external_message_id: str | None = None
    body: str
    attachments: list[dict] = Field(default_factory=list)
    delivery_status: str | None = None
    read_status: str | None = None
    metadata: dict = Field(default_factory=dict)
    sent_at: str
    created_at: str


class SalesCallWebhookIn(BaseModel):
    deal_id: str | None = None
    lead_id: str | None = None
    phone_number: str
    provider: str = "asterisk"
    external_call_id: str | None = None
    subject: str | None = None


class SalesCallCompleteIn(BaseModel):
    summary: str | None = None
    recording_url: str | None = None
    result_code: str | None = None


class SalesTranscriptIn(BaseModel):
    language: str = "ru"
    transcript_text: str = Field(min_length=1)
    diarization: dict = Field(default_factory=dict)
    extracted_entities: dict = Field(default_factory=dict)


class SalesTranscriptOut(BaseModel):
    transcript_id: str
    call_id: str
    language: str
    transcript_text: str
    diarization: dict = Field(default_factory=dict)
    extracted_entities: dict = Field(default_factory=dict)
    created_at: str
    updated_at: str


class SalesCallOut(BaseModel):
    call_id: str
    deal_id: str
    communication_id: str
    phone_number: str
    direction: SalesDirection
    provider: str
    external_call_id: str | None = None
    recording_url: str | None = None
    transcript_status: SalesTranscriptStatus
    transcript_id: str | None = None
    call_status: str
    started_at: str
    ended_at: str | None = None
    duration_sec: int | None = None
    summary: str | None = None
    created_at: str
    updated_at: str


class SalesOfferCreate(BaseModel):
    offer_type: SalesOfferType = "offer"
    title: str = Field(min_length=3)
    description: str | None = None
    line_items: list[dict] = Field(default_factory=list)
    pricing: dict = Field(default_factory=dict)
    total_amount: float = Field(ge=0)
    currency: str = "KZT"
    validity_until: str | None = None
    rendered_document_url: str | None = None


class SalesOfferOut(BaseModel):
    offer_id: str
    deal_id: str
    offer_type: SalesOfferType
    title: str
    description: str | None = None
    line_items: list[dict] = Field(default_factory=list)
    pricing: dict = Field(default_factory=dict)
    total_amount: float
    currency: str
    validity_until: str | None = None
    status: SalesOfferStatus
    rendered_document_url: str | None = None
    created_by_type: str
    created_at: str
    updated_at: str


class SalesConditionUpsertIn(BaseModel):
    product_name: str | None = None
    service_name: str | None = None
    quantity: float | None = Field(default=None, ge=0)
    unit: str | None = None
    delivery_mode: str | None = None
    execution_date: str | None = None
    start_date: str | None = None
    end_date: str | None = None
    payment_terms: str | None = None
    custom_terms: dict = Field(default_factory=dict)
    agreed_price: float | None = Field(default=None, ge=0)
    currency: str = "KZT"


class SalesConditionOut(BaseModel):
    condition_id: str
    deal_id: str
    product_name: str | None = None
    service_name: str | None = None
    quantity: float | None = None
    unit: str | None = None
    delivery_mode: str | None = None
    execution_date: str | None = None
    start_date: str | None = None
    end_date: str | None = None
    payment_terms: str | None = None
    custom_terms: dict = Field(default_factory=dict)
    agreed_price: float | None = None
    currency: str
    confirmed_at: str | None = None
    created_at: str
    updated_at: str


class SalesCounterpartyUpsertIn(BaseModel):
    company_name: str | None = None
    full_name: str | None = None
    bin_iin: str | None = None
    address: str | None = None
    bank_details: dict = Field(default_factory=dict)
    signer_name: str | None = None
    signer_role: str | None = None
    signer_basis: str | None = None
    email_for_docs: str | None = None
    phone_for_docs: str | None = None


class SalesCounterpartyOut(BaseModel):
    counterparty_id: str
    deal_id: str
    customer_id: str | None = None
    company_name: str | None = None
    full_name: str | None = None
    bin_iin: str | None = None
    address: str | None = None
    bank_details: dict = Field(default_factory=dict)
    signer_name: str | None = None
    signer_role: str | None = None
    signer_basis: str | None = None
    email_for_docs: str | None = None
    phone_for_docs: str | None = None
    completeness_status: str
    created_at: str
    updated_at: str


class SalesDocumentCreate(BaseModel):
    document_type: SalesDocumentType
    template_id: str | None = None
    version: int = Field(default=1, ge=1)
    rendered_payload: dict = Field(default_factory=dict)
    file_url: str | None = None


class SalesDocumentOut(BaseModel):
    document_id: str
    deal_id: str
    customer_id: str | None = None
    document_type: SalesDocumentType
    template_id: str | None = None
    version: int
    status: SalesDocumentStatus
    file_url: str | None = None
    rendered_payload: dict = Field(default_factory=dict)
    external_sign_provider_id: str | None = None
    signed_at: str | None = None
    created_at: str
    updated_at: str


class SalesInvoiceCreate(BaseModel):
    basis_document_id: str | None = None
    amount: float = Field(ge=0)
    currency: str = "KZT"
    due_date: str | None = None
    payment_link: str | None = None
    line_items: list[dict] = Field(default_factory=list)
    metadata: dict = Field(default_factory=dict)


class SalesInvoiceOut(BaseModel):
    invoice_id: str
    deal_id: str
    customer_id: str | None = None
    invoice_number: str
    basis_document_id: str | None = None
    amount: float
    currency: str
    due_date: str | None = None
    status: SalesInvoiceStatus
    payment_link: str | None = None
    line_items: list[dict] = Field(default_factory=list)
    metadata: dict = Field(default_factory=dict)
    issued_at: str | None = None
    paid_at: str | None = None
    created_at: str
    updated_at: str


class SalesPaymentWebhookIn(BaseModel):
    deal_id: str
    invoice_id: str | None = None
    payment_provider: str = "manual"
    provider_account_id: str | None = None
    external_event_id: str | None = None
    external_payment_id: str | None = None
    event_type: str | None = None
    provider_status: str | None = None
    amount: float = Field(ge=0)
    currency: str = "KZT"
    status: SalesPaymentStatus = "success"
    paid_at: str | None = None
    payment_method: str | None = None
    failure_reason: str | None = None
    metadata: dict = Field(default_factory=dict)


class SalesPaymentReconcileIn(BaseModel):
    status: SalesPaymentStatus
    failure_reason: str | None = None
    metadata: dict = Field(default_factory=dict)


class SalesPaymentOut(BaseModel):
    payment_id: str
    deal_id: str
    invoice_id: str | None = None
    payment_provider: str | None = None
    external_payment_id: str | None = None
    amount: float
    currency: str
    status: SalesPaymentStatus
    paid_at: str | None = None
    payment_method: str | None = None
    failure_reason: str | None = None
    metadata: dict = Field(default_factory=dict)
    created_at: str
    updated_at: str


class SalesEscalationCreateIn(BaseModel):
    escalation_type: str = Field(min_length=2)
    reason: str = Field(min_length=3)
    severity: SalesEscalationSeverity = "medium"
    assigned_to_user_id: str | None = None
    source_channel: str | None = None
    source_communication_session_id: str | None = None
    source_automation_task_id: str | None = None
    sla_due_at: str | None = None


class SalesEscalationOut(BaseModel):
    escalation_id: str
    deal_id: str
    escalation_type: str
    reason: str
    severity: SalesEscalationSeverity
    status: SalesEscalationStatus
    assigned_to_user_id: str | None = None
    assigned_at: str | None = None
    started_at: str | None = None
    created_at: str
    resolved_at: str | None = None
    canceled_at: str | None = None
    resolution_code: str | None = None
    resolution_summary: str | None = None
    sla_due_at: str | None = None
    source_channel: str | None = None
    source_communication_session_id: str | None = None
    source_automation_task_id: str | None = None
    updated_at: str | None = None


class SalesEscalationAssignIn(BaseModel):
    assigned_to_user_id: str = Field(min_length=1)


class SalesEscalationResolveIn(BaseModel):
    resolution_code: str = Field(min_length=2)
    resolution_summary: str | None = None
    target_stage_code: str | None = None
    metadata: dict = Field(default_factory=dict)


class SalesEscalationCancelIn(BaseModel):
    resolution_code: str = "canceled"
    resolution_summary: str | None = None
    metadata: dict = Field(default_factory=dict)


class SalesAutomationTaskOut(BaseModel):
    task_id: str
    deal_id: str
    deal_title: str | None = None
    deal_status: SalesDealStatus | None = None
    deal_stage_id: str | None = None
    deal_stage_code: str | None = None
    deal_pipeline_id: str | None = None
    task_type: str
    payload: dict = Field(default_factory=dict)
    run_at: str
    status: SalesAutomationStatus
    retry_count: int = 0
    max_retries: int = 3
    locked_at: str | None = None
    locked_by: str | None = None
    completed_at: str | None = None
    failed_at: str | None = None
    last_error: str | None = None
    recommended_to_channel: SalesSwitchChannel | str | None = None
    reason_code: str | None = None
    created_at: str
    updated_at: str


class SalesStageHistoryOut(BaseModel):
    history_id: str
    deal_id: str
    from_stage_id: str | None = None
    to_stage_id: str
    from_stage: SalesStageRefOut | None = None
    to_stage: SalesStageRefOut | None = None
    changed_by_type: str
    changed_by_id: str | None = None
    reason: str | None = None
    changed_at: str


class SalesChannelSwitchOut(BaseModel):
    switch_id: str
    deal_id: str
    communication_id: str | None = None
    communication_session_id: str | None = None
    previous_communication_session_id: str | None = None
    new_communication_session_id: str | None = None
    from_channel: str
    to_channel: str
    reason_code: str
    reason_text: str | None = None
    reason_for_channel_switch: str
    initiated_by_type: str
    initiated_by_id: str | None = None
    source_type: str | None = None
    source_id: str | None = None
    recommended_by_task_id: str | None = None
    switched_at: str
    created_at: str
    new_communication: SalesCommunicationOut | None = None


class SalesNoteCreateIn(BaseModel):
    note_type: str = "general"
    content: str = Field(min_length=1)
    source_type: str | None = None
    source_id: str | None = None


class SalesNoteUpdateIn(BaseModel):
    note_type: str | None = None
    content: str | None = Field(default=None, min_length=1)
    source_type: str | None = None
    source_id: str | None = None


class SalesNoteOut(BaseModel):
    note_id: str
    deal_id: str
    author_type: str
    author_id: str | None = None
    note_type: str
    content: str
    source_type: str | None = None
    source_id: str | None = None
    created_at: str
    updated_at: str | None = None
    archived_at: str | None = None


class SalesTimelineEventOut(BaseModel):
    ts: str
    kind: str
    title: str
    body: str
    meta: dict = Field(default_factory=dict)


class SalesWorkspaceOut(BaseModel):
    lead: SalesLeadOut | None = None
    deal: SalesDealOut
    pipeline: SalesPipelineOut | None = None
    stage: SalesStageRefOut | None = None
    communications: list[SalesCommunicationOut] = Field(default_factory=list)
    messages: list[SalesMessageOut] = Field(default_factory=list)
    calls: list[SalesCallOut] = Field(default_factory=list)
    transcripts: list[SalesTranscriptOut] = Field(default_factory=list)
    notes: list[SalesNoteOut] = Field(default_factory=list)
    offers: list[SalesOfferOut] = Field(default_factory=list)
    conditions: list[SalesConditionOut] = Field(default_factory=list)
    counterparty: SalesCounterpartyOut | None = None
    documents: list[SalesDocumentOut] = Field(default_factory=list)
    invoices: list[SalesInvoiceOut] = Field(default_factory=list)
    payments: list[SalesPaymentOut] = Field(default_factory=list)
    escalations: list[SalesEscalationOut] = Field(default_factory=list)
    active_escalation: SalesEscalationOut | None = None
    tasks: list[SalesAutomationTaskOut] = Field(default_factory=list)
    stage_history: list[SalesStageHistoryOut] = Field(default_factory=list)
    channel_switches: list[SalesChannelSwitchOut] = Field(default_factory=list)
    recommended_channel_switch: dict | None = None
    timeline: list[SalesTimelineEventOut] = Field(default_factory=list)


class SalesDashboardStageOut(BaseModel):
    stage_id: str
    label: str
    stage: SalesStageRefOut | None = None
    count: int = 0
    amount: float = 0.0


class SalesDashboardSummaryOut(BaseModel):
    leads_total: int = 0
    deals_active: int = 0
    deals_won: int = 0
    deals_lost: int = 0
    overdue_invoices: int = 0
    payment_expected: float = 0.0
    payment_received: float = 0.0
    voice_sessions: int = 0
    text_sessions: int = 0
    channel_switches: int = 0
    human_escalations: int = 0
    stage_counts: list[SalesDashboardStageOut] = Field(default_factory=list)
    hottest_deals: list[SalesDealOut] = Field(default_factory=list)


class SalesTelegramSyncIn(BaseModel):
    thread_id: str = Field(min_length=1)
    chat_id: str = Field(min_length=1)
    interaction_id: str | None = None
    customer_id: str | None = None
    phone_number: str | None = None
    display_name: str | None = None
    queue_id: str | None = None
    status: str | None = None
    ai_state: str | None = None
    ai_handoff_reason: str | None = None
    message_id: str | None = None
    external_message_id: str | None = None
    text: str | None = None
    direction: str = "inbound"
    author_type: str | None = None
    author_id: str | None = None
    happened_at: str | None = None
    metadata: dict = Field(default_factory=dict)


class SalesVoiceSyncIn(BaseModel):
    call_id: str = Field(min_length=1)
    interaction_id: str | None = None
    queue_id: str | None = None
    queue_code: str | None = None
    caller_number: str | None = None
    caller_name: str | None = None
    voice_session_id: str | None = None
    ai_session_id: str | None = None
    ai_state: str | None = None
    handoff_reason: str | None = None
    telephony_status: str | None = None
    call_status: str | None = None
    started_at: str | None = None
    ended_at: str | None = None
    summary: str | None = None
    transcript_text: str | None = None
    metadata: dict = Field(default_factory=dict)
