"""
GovernanceRemediationDispatch Pydantic Schemas
================================================
Wave 2 D: 治理事件修復派遣的輸入/輸出驗證 schema。

用途：
- DecisionContextV1: JSONB 欄位結構驗證（service 層寫入前必須通過）
- DispatchCreate:    建立 dispatch 的輸入驗證
- DispatchResponse:  單筆 dispatch API 回應
- DispatchListItem:  列表頁輕量回應（含 /governance Queue tab）

設計原則：
- Pydantic V2（對齊 models/ 目錄）
- DecisionContextV1 版本化：version 欄位方便 fine-tune pipeline 過濾相容版本
- 所有時間欄位使用 datetime（含 timezone，台北時區）

2026-05-03 ogt + Claude Sonnet 4.6（亞太）: Wave 2 D db-expert spec 實作
"""

from __future__ import annotations

from datetime import datetime
from typing import Any, Literal

from pydantic import BaseModel, Field


# =============================================================================
# DecisionContextV1 — JSONB 欄位驗證（service 層寫入 DB 前強制驗證）
# =============================================================================

class DecisionContextV1(BaseModel):
    """治理派遣決策上下文 v1.

    service 層必須用此 model 驗證後序列化為 dict 再寫入 decision_context 欄位。
    版本欄位方便未來 schema 演進時過濾不相容記錄。

    欄位均 optional：允許部分感官缺失（MCP 呼叫失敗時為 None）。
    """

    version: Literal["v1"] = Field(
        default="v1",
        description="schema 版本，固定為 v1",
    )
    trigger_source: str | None = Field(
        default=None,
        description="觸發來源（如 governance_agent / trust_drift_watchdog）",
    )
    triggered_metric: str | None = Field(
        default=None,
        description="觸發指標名稱（如 avg_trust_score / hallucination_rate）",
    )
    metric_value: float | None = Field(
        default=None,
        description="觸發時的指標數值",
    )
    threshold: float | None = Field(
        default=None,
        description="觸發閾值",
    )
    affected_resources: list[str] = Field(
        default_factory=list,
        description="受影響的資源列表（如 playbook_id / km_entry_id）",
    )
    suggested_action: str | None = Field(
        default=None,
        description="AI 建議的修復動作摘要（≤200 字）",
    )
    extra: dict[str, Any] = Field(
        default_factory=dict,
        description="其他擴充欄位（預留 forward compatibility）",
    )


# =============================================================================
# DispatchCreate — 建立 dispatch 的輸入驗證
# =============================================================================

class DispatchCreate(BaseModel):
    """建立新 dispatch 的輸入 schema.

    service 層呼叫 create_dispatch() 前先用此 schema 驗證輸入。
    decision_context 在此層以 DecisionContextV1 驗證，序列化後寫入 DB。
    """

    governance_event_id: str = Field(
        description="關聯的 ai_governance_events.id（UUID）"
    )
    event_type: Literal[
        "trust_drift",
        "knowledge_degradation",
        "llm_hallucination",
        "execution_blast_radius",
        "governance_slo_data_gap",
    ] = Field(description="治理事件類型")
    executor_type: str = Field(
        max_length=80,
        description="執行器類型（如 playbook_executor / manual / slo_repair）",
    )
    playbook_id: str | None = Field(
        default=None,
        description="可選，關聯 playbooks.playbook_id",
    )
    incident_id: str | None = Field(
        default=None,
        description="可選，關聯 incidents.incident_id",
    )
    approval_id: str | None = Field(
        default=None,
        description="可選，關聯 approval_records.id",
    )
    decision_context: DecisionContextV1 = Field(
        default_factory=DecisionContextV1,
        description="決策上下文（DecisionContextV1 強制驗證）",
    )
    max_attempts: int = Field(
        default=3,
        ge=1,
        description="最大重試次數（含首次，必須 >= 1）",
    )
    created_by: str | None = Field(
        default="governance_dispatcher",
        description="建立者（系統自動派遣時為 governance_dispatcher）",
    )


# =============================================================================
# DispatchResponse — 單筆 dispatch 完整回應
# =============================================================================

class DispatchResponse(BaseModel):
    """單筆 GovernanceRemediationDispatch API 回應."""

    id: str
    governance_event_id: str
    event_type: str
    dispatch_status: str
    playbook_id: str | None = None
    incident_id: str | None = None
    approval_id: str | None = None
    decision_context: dict[str, Any]
    executor_type: str
    attempt_count: int
    max_attempts: int
    last_error: str | None = None
    dispatched_at: datetime
    started_at: datetime | None = None
    completed_at: datetime | None = None
    created_by: str | None = None

    model_config = {"from_attributes": True}


# =============================================================================
# DispatchListItem — 列表頁輕量回應（/governance Queue tab 用）
# =============================================================================

class DispatchListItem(BaseModel):
    """列表頁輕量 dispatch 回應.

    僅回傳 Queue / Events tab 所需欄位，避免傳輸完整 decision_context。
    """

    id: str
    governance_event_id: str
    event_type: str
    dispatch_status: str
    executor_type: str
    playbook_id: str | None = None
    attempt_count: int
    max_attempts: int
    dispatched_at: datetime
    completed_at: datetime | None = None

    model_config = {"from_attributes": True}
