"""
Governance API Models — /governance 頁面 Pydantic Schemas
=========================================================
PR 1 後端 3 endpoint 的 request/response schema.

Endpoints:
  GET /api/v1/ai/governance/events   — ai_governance_events 查詢
  GET /api/v1/ai/governance/queue    — governance_remediation_dispatch 隊列（Track D 依賴表）
  GET /api/v1/ai/governance/summary  — 30d SLO 違反時序統計

設計原則:
- Pydantic V2，對齊 models/ 目錄
- Severity 映射邏輯集中於此，Router / Service 直接用
- 禁止硬編碼 IP 或內網位址

2026-05-02 ogt + Claude Sonnet 4.6 Asia/Taipei
"""

from __future__ import annotations

from datetime import datetime
from typing import Literal

from pydantic import BaseModel, Field

# =============================================================================
# Severity 映射
# =============================================================================

# critical: slo_violation / conservative_mode / governance_slo_data_gap
# warning:  trust_drift / kb_stale / knowledge_degradation / execution_blast_radius
# info:     其他（含 replay_degraded / self_demotion / llm_hallucination 等）

_CRITICAL_TYPES: frozenset[str] = frozenset({
    "slo_violation",
    "conservative_mode",
    "governance_slo_data_gap",
})

_WARNING_TYPES: frozenset[str] = frozenset({
    "trust_drift",
    "kb_stale",
    "knowledge_degradation",
    "execution_blast_radius",
})


def map_severity(event_type: str) -> Literal["critical", "warning", "info"]:
    """將 event_type 映射為 severity 等級."""
    if event_type in _CRITICAL_TYPES:
        return "critical"
    if event_type in _WARNING_TYPES:
        return "warning"
    return "info"


# =============================================================================
# Endpoint 1: events
# =============================================================================

class GovernanceEvent(BaseModel):
    id: str
    event_type: str
    severity: Literal["critical", "warning", "info"]
    triggered_at: datetime
    resolved: bool
    resolved_at: datetime | None = None
    impact: str = Field(description="≤80 字摘要，從 details 抽取")
    details: dict
    remediation: str | None = None
    dispatch_ids: list[str] = Field(default_factory=list)


class GovernanceEventsResponse(BaseModel):
    items: list[GovernanceEvent]
    total: int
    page: int
    size: int


# =============================================================================
# Endpoint 2: queue
# =============================================================================

class DispatchItem(BaseModel):
    id: str
    governance_event_id: str
    event_type: str
    dispatch_status: str
    proposed_action: str = Field(description="≤120 字動作摘要")
    playbook_id: str | None = None
    playbook_trust: float | None = Field(default=None, ge=0.0, le=1.0)
    created_at: datetime
    dispatched_at: datetime | None = None
    completed_at: datetime | None = None
    operator_note: str | None = None


class GovernanceQueueResponse(BaseModel):
    items: list[DispatchItem]
    total: int
    page: int
    size: int
    table_pending: bool = Field(
        default=False,
        description="dispatch 表尚未建立時為 True",
    )


# =============================================================================
# Endpoint 3: summary
# =============================================================================

class DailyCount(BaseModel):
    date: str = Field(description="YYYY-MM-DD")
    total: int
    by_type: dict[str, int] = Field(description="{event_type: count}")


class GovernanceSummaryResponse(BaseModel):
    compliance_rate: float = Field(description="0.0-1.0，1 - unresolved/total")
    total_events: int
    unresolved_count: int
    daily_counts: list[DailyCount]
