"""Deal Desk lifecycle context contracts."""

from __future__ import annotations

from typing import Any, Literal

from pydantic import BaseModel, ConfigDict, Field, computed_field


class _DealDeskContextModel(BaseModel):
    model_config = ConfigDict(extra="ignore")

    def to_dict(self) -> dict[str, Any]:
        return self.model_dump(exclude_none=False, by_alias=True)

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> "_DealDeskContextModel":
        return cls.model_validate(data)


CloseWorkflowState = Literal[
    "deal_active",
    "submitted_for_close",
    "certifying",
    "certified",
    "exception_pending",
    "closed_won_progressed",
    "post_close_executed",
]


class DealAssumption(_DealDeskContextModel):
    key: str
    value: Any
    confidence: float = Field(default=0.0, ge=0.0, le=1.0)
    rationale: str = ""
    status: Literal["open", "confirmed", "rejected"] = "open"


class ApprovalDecision(_DealDeskContextModel):
    actor: str
    actor_role: str | None = None
    decision: Literal["approved", "rejected", "overridden"]
    channel: str | None = None
    decided_at: str
    rationale: str | None = None
    receipt_id: str | None = None


class QuoteRef(_DealDeskContextModel):
    quote_id: str
    engine: Literal["standard_quotes", "salesforce_cpq", "third_party"]
    status: str
    created_at: str | None = None
    pdf_artifact_path: str | None = None


class ArtifactRef(_DealDeskContextModel):
    type: Literal[
        "quote_pdf",
        "close_packet",
        "reconciliation_packet",
        "close_certification_run",
        "receipt",
        "approval_export",
        "post_close_trigger_receipt",
    ]
    path: str
    created_at: str | None = None


class DealContextV1(_DealDeskContextModel):
    version: int = 1
    context_id: str
    crm_org_id: str
    org_alias: str | None = None
    opportunity_id: str
    account_id: str | None = None

    created_at: str
    updated_at: str | None = None
    lifecycle_state: str
    close_workflow_state: CloseWorkflowState = "deal_active"
    close_submitted_at: str | None = None
    archived: bool = False

    inferred_motion_id: str | None = None
    inferred_motion_confidence: float = Field(default=0.0, ge=0.0, le=1.0)
    archetype_id: str | None = None
    pattern_profile_id: str | None = None
    environment_profile_id: str | None = None

    confidence_at_creation: float | None = Field(default=None, ge=0.0, le=1.0)
    original_request: dict[str, Any] = Field(default_factory=dict)
    normalized_quote_request: dict[str, Any] = Field(default_factory=dict)
    assumptions: list[DealAssumption] = Field(default_factory=list)
    assumptions_at_creation: list[DealAssumption] = Field(default_factory=list)
    evidence_ids: list[str] = Field(default_factory=list)

    approval_chain: list[ApprovalDecision] = Field(default_factory=list)
    quote_refs: list[QuoteRef] = Field(default_factory=list)
    receipt_ids: list[str] = Field(default_factory=list)
    artifact_refs: list[ArtifactRef] = Field(default_factory=list)

    close_findings: list[str] = Field(default_factory=list)
    close_packet_paths: list[str] = Field(default_factory=list)
    reconciliation_packet_paths: list[str] = Field(default_factory=list)
    latest_reconciliation_packet_id: str | None = None
    renewal_opportunity_id: str | None = None

    @computed_field(alias="$schema")
    @property
    def schema(self) -> str:
        return "DealContext/v1"

    @property
    def canonical_key(self) -> str:
        return self.opportunity_id


__all__ = [
    "DealAssumption",
    "ApprovalDecision",
    "QuoteRef",
    "ArtifactRef",
    "CloseWorkflowState",
    "DealContextV1",
]
