"""
Terminal Models
===============
Phase 19.1 - Omni-Terminal API Models

Pydantic models for Terminal SSE communication.

@see ADR-031 Omni-Terminal SSE Architecture
@author Claude Code (首席架構師)
@version 1.0.0
@date 2026-03-28 (台北時間)
"""

from datetime import UTC, datetime
from enum import Enum
from typing import Any

from pydantic import BaseModel, Field

# =============================================================================
# Enums
# =============================================================================


class TerminalSessionStatus(str, Enum):
    """Terminal Session 狀態"""

    PENDING = "pending"
    PROCESSING = "processing"
    COMPLETED = "completed"
    ABORTED = "aborted"
    ERROR = "error"


# =============================================================================
# Request Models
# =============================================================================


class SpatialContext(BaseModel):
    """
    空間感知上下文 (Ghost Payload)

    前端隱形夾帶，讓 AI 知道使用者正在看什麼
    """

    current_page: str = Field(
        ...,
        description="統帥當前所在的路由",
        examples=["/zh-TW/authorizations", "/zh-TW"],
    )
    focused_entity_id: str | None = Field(
        default=None,
        description="正在檢視的實體 ID (incident/approval)",
        examples=["INC-2026-0001", "APR-2026-0001"],
    )


class TerminalIntentRequest(BaseModel):
    """
    Terminal Intent 請求

    統帥輸入的指令或問題
    """

    intent: str = Field(
        ...,
        description="統帥輸入的原始指令或意圖",
        min_length=1,
        max_length=2000,
        examples=["列出所有待審核的 approval", "為什麼 awoooi-api pod 一直重啟？"],
    )
    context: SpatialContext = Field(
        ...,
        description="前端空間感知上下文",
    )
    session_id: str | None = Field(
        default=None,
        description="現有 Session ID (用於續傳)",
    )


class TerminalAbortRequest(BaseModel):
    """中斷執行請求"""

    reason: str | None = Field(
        default=None,
        description="中斷原因",
    )


# =============================================================================
# Response Models
# =============================================================================


class TerminalIntentResponse(BaseModel):
    """
    Intent 請求回應

    返回 session_id 供前端訂閱 SSE
    """

    session_id: str = Field(
        ...,
        description="Session UUID",
    )
    stream_url: str = Field(
        ...,
        description="SSE 串流訂閱 URL",
    )
    created_at: datetime = Field(
        default_factory=lambda: datetime.now(UTC),
    )


class TerminalStatusResponse(BaseModel):
    """Session 狀態查詢回應"""

    session_id: str
    status: TerminalSessionStatus
    created_at: datetime
    last_event_id: int
    message_count: int


class TerminalAbortResponse(BaseModel):
    """中斷執行回應"""

    session_id: str
    aborted: bool
    message: str


# =============================================================================
# SSE Event Models
# =============================================================================


class TerminalThoughtEvent(BaseModel):
    """AI 思考軌跡事件"""

    agent: str = Field(
        ...,
        description="代理人名稱",
        examples=["System", "Investigator", "Strategist"],
    )
    msg: str = Field(
        ...,
        description="思考內容",
    )


class TerminalToolCallEvent(BaseModel):
    """工具呼叫事件"""

    tool: str = Field(
        ...,
        description="工具名稱",
        examples=["K8s-Log-Scanner", "Sentry-Query", "Playbook-Lookup"],
    )
    status: str = Field(
        ...,
        description="執行狀態",
        examples=["executing", "completed", "failed"],
    )
    result: Any | None = Field(
        default=None,
        description="執行結果",
    )


class TerminalRenderUIEvent(BaseModel):
    """GenUI 渲染事件"""

    component: str = Field(
        ...,
        description="組件名稱 (必須在前端 Registry 中)",
        examples=["ApprovalCard", "MetricsSummaryCard", "SentryErrorCard"],
    )
    props: dict[str, Any] = Field(
        default_factory=dict,
        description="組件 Props",
    )
    position: str = Field(
        default="inline",
        description="渲染位置",
        examples=["inline", "modal", "panel"],
    )
    id: str | None = Field(
        default=None,
        description="組件 ID (用於更新/移除)",
    )


class TerminalActionRequestEvent(BaseModel):
    """核鑰授權請求事件"""

    approval_id: str = Field(
        ...,
        description="Approval ID",
    )
    risk_level: str = Field(
        ...,
        description="風險等級",
        examples=["LOW", "MEDIUM", "CRITICAL"],
    )
    kubectl: str = Field(
        ...,
        description="要執行的 kubectl 命令",
    )
    description: str | None = Field(
        default=None,
        description="操作說明",
    )


class TerminalCompleteEvent(BaseModel):
    """串流完成事件"""

    session_id: str
    message: str = "Stream completed"


class TerminalErrorEvent(BaseModel):
    """錯誤事件"""

    session_id: str
    error_code: str
    message: str
    recoverable: bool = True


# =============================================================================
# Session Model (Redis Storage)
# =============================================================================


class TerminalSession(BaseModel):
    """
    Terminal Session

    儲存在 Redis，TTL 5 分鐘
    """

    session_id: str
    user_id: str | None = None
    intent: str
    context: SpatialContext
    status: TerminalSessionStatus = TerminalSessionStatus.PENDING
    created_at: datetime = Field(default_factory=lambda: datetime.now(UTC))
    last_event_id: int = 0
    message_count: int = 0

    def next_event_id(self) -> int:
        """取得下一個事件 ID"""
        self.last_event_id += 1
        return self.last_event_id
