"""
CMDC SDK 数据类型定义。

所有 15 种对外事件类型、SessionOptions、Stats、Message 等。
"""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any


# ---------------------------------------------------------------------------
# 基础消息
# ---------------------------------------------------------------------------


@dataclass
class Message:
    """对话历史消息。"""

    role: str
    """消息角色：'user' / 'assistant' / 'system' / 'tool_result'"""

    content: str
    """消息文本内容。"""

    tool_calls: list[dict[str, Any]] = field(default_factory=list)
    """工具调用列表（仅 assistant 消息可能包含）。"""


# ---------------------------------------------------------------------------
# Session 配置
# ---------------------------------------------------------------------------


@dataclass
class SessionOptions:
    """创建 Session 的配置选项。"""

    model: str
    """LLM 模型标识，格式 'provider:model'，如 'deepseek:deepseek-chat'。"""

    session_id: str | None = None
    """自定义 Session ID；为 None 时服务端自动生成 16 位 hex。"""

    system_prompt: str | None = None
    """Agent 系统提示词。"""

    working_dir: str | None = None
    """工具工作根目录，默认 '.'。"""

    tools: list[str] = field(default_factory=list)
    """启用的 CMDC Tool 模块名列表，如 ['CMDC.Tool.Shell', 'CMDC.Tool.ReadFile']。"""

    plugins: list[str] = field(default_factory=list)
    """启用的 CMDC Plugin 模块名列表。"""

    blueprint: str | None = None
    """Blueprint 模块名，定义 Agent 的完整配置模板。"""

    max_turns: int | None = None
    """最大 Agent 轮次数，默认 100。"""

    max_tokens: int | None = None
    """LLM 单次回复最大输出 token 数。"""

    skills_dirs: list[str] = field(default_factory=list)
    """Skill 文件扫描目录列表。"""

    provider_opts: dict[str, Any] = field(default_factory=dict)
    """透传给 LLM Provider 的额外参数，如 {'temperature': 0.7}。"""

    def to_dict(self) -> dict[str, Any]:
        """序列化为 Gateway API 请求体（camelCase）。"""
        payload: dict[str, Any] = {"model": self.model}
        if self.session_id is not None:
            payload["sessionId"] = self.session_id
        if self.system_prompt is not None:
            payload["systemPrompt"] = self.system_prompt
        if self.working_dir is not None:
            payload["workingDir"] = self.working_dir
        if self.tools:
            payload["tools"] = self.tools
        if self.plugins:
            payload["plugins"] = self.plugins
        if self.blueprint is not None:
            payload["blueprint"] = self.blueprint
        if self.max_turns is not None:
            payload["maxTurns"] = self.max_turns
        if self.max_tokens is not None:
            payload["maxTokens"] = self.max_tokens
        if self.skills_dirs:
            payload["skillsDirs"] = self.skills_dirs
        if self.provider_opts:
            payload["providerOpts"] = self.provider_opts
        return payload


# ---------------------------------------------------------------------------
# Session 状态
# ---------------------------------------------------------------------------


@dataclass
class SessionInfo:
    """Session 当前状态。"""

    session_id: str
    state: str
    """Agent 状态：'idle' / 'working' / 'waiting_approval' / 'waiting_input'"""
    turns: int
    tool_calls: int
    total_tokens: int
    uptime_ms: int


# ---------------------------------------------------------------------------
# 统计
# ---------------------------------------------------------------------------


@dataclass
class TokenUsage:
    """Token 用量统计。"""

    prompt_tokens: int
    completion_tokens: int
    total_tokens: int


@dataclass
class Stats:
    """Session 用量统计。"""

    session_id: str
    turns: int
    total_tokens: int
    cost_usd: float
    prompt_count: int
    token_usage: TokenUsage


# ---------------------------------------------------------------------------
# Prompt 响应
# ---------------------------------------------------------------------------


@dataclass
class PromptResponse:
    """POST /prompt 的立即响应。"""

    request_id: str
    session_id: str
    queued: bool


# ---------------------------------------------------------------------------
# 健康检查
# ---------------------------------------------------------------------------


@dataclass
class HealthInfo:
    """GET /healthz 响应。"""

    status: str
    version: str
    active_sessions: int
    tracked_keys: int
    timestamp: str


# ---------------------------------------------------------------------------
# 15 种 SSE 事件
# ---------------------------------------------------------------------------


@dataclass
class Event:
    """CMDC Gateway 对外事件。

    type 取值（15 种）：
        - agent_start
        - agent_end
        - agent_abort
        - prompt_received
        - message_start
        - message_delta
        - thinking_start
        - thinking_delta
        - tool_calls
        - tool_execution_start
        - tool_execution_end
        - approval_required
        - approval_resolved
        - ask_user
        - error
    """

    type: str
    """事件类型。"""

    data: dict[str, Any]
    """事件数据，字段因 type 而异。"""

    # 便捷属性 — message_delta ------------------------------------------------

    @property
    def delta(self) -> str | None:
        """流式文本增量（message_delta 事件专用）。"""
        return self.data.get("delta")

    # 便捷属性 — agent_end ----------------------------------------------------

    @property
    def last_message(self) -> Message | None:
        """最后一条 assistant 消息（agent_end 事件专用）。"""
        msg = self.data.get("lastMessage")
        if msg is None:
            return None
        return Message(role=msg.get("role", ""), content=msg.get("content", ""))

    @property
    def token_usage(self) -> TokenUsage | None:
        """Token 用量（agent_end 事件专用）。"""
        usage = self.data.get("tokenUsage")
        if usage is None:
            return None
        return TokenUsage(
            prompt_tokens=usage.get("promptTokens", 0),
            completion_tokens=usage.get("completionTokens", 0),
            total_tokens=usage.get("totalTokens", 0),
        )

    # 便捷属性 — approval_required --------------------------------------------

    @property
    def approval_id(self) -> str | None:
        """审批 ID（approval_required / approval_resolved 事件专用）。"""
        return self.data.get("approvalId")

    # 便捷属性 — ask_user -----------------------------------------------------

    @property
    def ask_ref(self) -> str | None:
        """提问引用 ID（ask_user 事件专用）。"""
        return self.data.get("ref")

    @property
    def question(self) -> str | None:
        """Agent 问题文本（ask_user 事件专用）。"""
        return self.data.get("question")

    def __repr__(self) -> str:
        return f"Event(type={self.type!r}, data={self.data!r})"
