"""Close certification history contracts and document summary helpers."""

from __future__ import annotations

from dataclasses import dataclass
from typing import Any

from pydantic import BaseModel, ConfigDict, Field, computed_field

from .extraction import CloseDocumentEvidenceV1


class _DealDeskHistoryModel(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]) -> "_DealDeskHistoryModel":
        return cls.model_validate(data)


@dataclass(frozen=True)
class CloseDocumentEvidenceSummary:
    row_count: int
    confidence_sum: float
    confidence_avg: float | None
    confidence_min: float | None
    confidence_max: float | None
    method_counts: dict[str, int]


class CloseCertificationRunV1(_DealDeskHistoryModel):
    version: int = 1
    run_id: str
    opportunity_id: str
    crm_org_id: str
    org_alias: str | None = None
    context_id: str | None = None
    entrypoint: str
    triggered_at: str
    close_submitted_at: str | None = None
    lifecycle_state: str
    close_workflow_state: str
    overall_disposition: str
    reconciliation_packet_id: str
    reconciliation_packet_path: str
    blocker_count: int = 0
    approval_required_count: int = 0
    auto_fixable_count: int = 0
    document_evidence_status: str = "not_required"
    document_candidate_count: int = 0
    document_contract_candidate_count: int = 0
    document_summary: str = ""
    document_extraction_status: str = "not_attempted"
    document_evidence_count: int = 0
    document_comparison_count: int = 0
    document_discrepancy_count: int = 0
    document_evidence_summary: str = ""
    document_extraction_method_counts: dict[str, int] = Field(default_factory=dict)
    document_extraction_confidence_avg: float | None = Field(default=None, ge=0.0, le=1.0)
    document_extraction_confidence_min: float | None = Field(default=None, ge=0.0, le=1.0)
    document_extraction_confidence_max: float | None = Field(default=None, ge=0.0, le=1.0)
    document_extraction_confidence_sum: float = Field(default=0.0, ge=0.0)
    document_escalated: bool = False
    quote_integrity_status: str = "not_available"
    quote_integrity_summary: str = ""
    quote_integrity_discrepancy_count: int = 0
    quote_fingerprint_count: int = 0
    quote_binary_mismatch_count: int = 0
    quote_semantic_mismatch_count: int = 0
    quote_integrity_escalated: bool = False
    progression_status: str = "not_attempted"
    progression_target_stage: str | None = None
    progression_receipt_run_id: str | None = None
    progression_approval_required: bool = False
    progression_pending_run_id: str | None = None
    post_close_status: str = "not_attempted"
    post_close_trigger_run_ids: list[str] = Field(default_factory=list)
    post_close_trigger_status_counts: dict[str, int] = Field(default_factory=dict)
    post_close_approval_required: bool = False
    post_close_pending_run_id: str | None = None

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


def document_evidence_escalated(
    *,
    document_evidence_status: str | None,
    document_discrepancy_count: int | None,
    document_extraction_status: str | None,
) -> bool:
    evidence_status = str(document_evidence_status or "").strip().lower()
    if evidence_status in {"missing", "ambiguous"}:
        return True
    if int(document_discrepancy_count or 0) > 0:
        return True
    extraction_status = str(document_extraction_status or "").strip().lower()
    return extraction_status in {"partial", "unsupported"}


def summarize_close_document_evidence(
    evidence: list[CloseDocumentEvidenceV1] | None,
) -> CloseDocumentEvidenceSummary:
    rows = list(evidence or [])
    confidences = [float(item.confidence or 0.0) for item in rows]
    method_counts: dict[str, int] = {}
    for item in rows:
        method = str(item.extraction_method or "").strip() or "unknown"
        method_counts[method] = method_counts.get(method, 0) + 1
    if not confidences:
        return CloseDocumentEvidenceSummary(
            row_count=0,
            confidence_sum=0.0,
            confidence_avg=None,
            confidence_min=None,
            confidence_max=None,
            method_counts=method_counts,
        )
    confidence_sum = float(sum(confidences))
    return CloseDocumentEvidenceSummary(
        row_count=len(confidences),
        confidence_sum=round(confidence_sum, 6),
        confidence_avg=round(confidence_sum / float(len(confidences)), 6),
        confidence_min=round(min(confidences), 6),
        confidence_max=round(max(confidences), 6),
        method_counts=method_counts,
    )


__all__ = [
    "CloseCertificationRunV1",
    "CloseDocumentEvidenceSummary",
    "document_evidence_escalated",
    "summarize_close_document_evidence",
]
