#  coding=utf-8
# 本文档定义了 TurboAgent项目下的 外部平台（Platform）以及关联授权的基础数据模型
from __future__ import annotations

from enum import Enum
from typing import Any, Dict, List, Optional
from datetime import datetime

from pydantic import BaseModel, Field

from turbo_agent_core.schema.enums import (
    JSON,
    AuthType,
    Availablility
)

from turbo_agent_core.schema.basic import Endpoint

class AuthMethod(BaseModel):
    id: str = Field(description="授权方式 ID。")
    name: str = Field(description="授权方式名称。")
    authType: AuthType = Field(default=AuthType.APIKey, description="授权类型。")
    description: Optional[str] = Field(default=None, description="授权方式描述。")
    loginFlow: Optional[JSON] = Field(default=None, description="登录流程定义。")
    loginFieldsSchema: Optional[JSON] = Field(default=None, description="登录字段 Schema。")
    refreshFlow: Optional[JSON] = Field(default=None, description="刷新凭据流程定义。")
    refreshFieldsSchema: Optional[JSON] = Field(default=None, description="刷新凭据字段 Schema。")
    authFieldsSchema: Optional[JSON] = Field(default=None, description="授权字段 Schema。")
    authFieldPlacements: Optional[JSON] = Field(default=None, description="授权字段在请求中的放置规则。")
    responseMapping: Optional[JSON] = Field(default=None, description="登录或刷新响应字段映射规则。")
    defaultValiditySeconds: Optional[int] = Field(default=None, description="默认有效期，单位秒。")
    refreshBeforeSeconds: Optional[int] = Field(default=None, description="提前多久触发刷新，单位秒。")

class Secret(BaseModel):
    id: str = Field(description="凭据 ID。")
    name: str = Field(default="", description="凭据显示名称。")
    identifier: str = Field(default="", description="凭据业务标识，例如账户名或邮箱。")
    availability: Availablility = Field(default=Availablility.personal_visible, description="凭据可见性范围。")
    credential: Optional[JSON] = Field(default=None, description="凭据核心数据，如 access_token、refresh_token、api_key、cookies。")
    authDataSources: Optional[JSON] = Field(default=None, description="授权数据来源说明。")
    loginPayload: Optional[JSON] = Field(default=None, description="第一阶段登录字段数据，便于服务端代办登录。")
    autoLoginEnabled: bool = Field(default=False, description="是否允许服务端自动登录刷新凭据。")
    expiresAt: Optional[datetime] = Field(default=None, description="凭据过期时间。")
    validFrom: Optional[datetime] = Field(default=None, description="凭据生效时间。")
    lastRefreshed: Optional[datetime] = Field(default=None, description="最近刷新时间。")
    authMethodId: Optional[str] = Field(default=None, description="关联的授权方式 ID。")
    platformId: Optional[str] = Field(default=None, description="关联的平台 ID。")

class Platform(BaseModel):
    id: str = Field(description="平台 ID。")
    image_url: str = Field(description="平台图标地址。")
    name_en: str = Field(description="平台英文名。")
    name: str = Field(description="平台显示名称。")
    officialUrl: str = Field(description="平台官网地址。")
    description: str = Field(description="平台描述。")
    endpoint: Endpoint = Field(description="平台默认 API 访问端点。")
    secrets: List[Secret] = Field(default_factory=list, description="平台下可用的凭据列表。")
    authMethods: List[AuthMethod] = Field(default_factory=list, description="平台支持的授权方式列表。")


class DeviceResourceStats(BaseModel):
    """设备资源状态（具身/桌面本机）。

    说明：
    - 本结构仅用于协议与数据交换，不约束采集方式。
    - 采集实现由 server/local 决定（如 psutil、系统 API、硬件 SDK）。
    """

    timestamp_ms: Optional[float] = Field(default=None, description="采样时间戳，单位毫秒。")
    cpu_percent: Optional[float] = Field(default=None, description="CPU 使用率百分比。")
    mem_used_bytes: Optional[int] = Field(default=None, description="已使用内存字节数。")
    mem_total_bytes: Optional[int] = Field(default=None, description="总内存字节数。")
    battery_percent: Optional[float] = Field(default=None, description="电池电量百分比。")
    battery_is_charging: Optional[bool] = Field(default=None, description="当前是否正在充电。")
    extra: Optional[JSON] = Field(default=None, description="额外资源统计数据。")


class McpTransport(str, Enum):
    """MCP 服务的连接方式。"""
    stdio = "stdio"
    http = "http"
    ws = "ws"


class McpServerSpec(BaseModel):
    """MCP 服务描述（与 Platform 同层）。"""

    id: str = Field(description="MCP 服务 ID。")
    name: str = Field(description="MCP 服务名称。")
    description: Optional[str] = Field(default=None, description="MCP 服务描述。")

    transport: McpTransport = Field(default=McpTransport.stdio, description="MCP 服务传输方式。")

    # 对于 http/ws 模式：可使用 endpoint 描述访问地址
    endpoint: Optional[Endpoint] = Field(default=None, description="当 transport 为 http/ws 时使用的访问端点。")

    # 对于 stdio 模式：可用 command/args/env 描述进程启动参数（实现由 local 负责）
    command: Optional[str] = Field(default=None, description="当 transport 为 stdio 时使用的启动命令。")
    args: List[str] = Field(default_factory=list, description="启动命令参数列表。")
    env: Dict[str, str] = Field(default_factory=dict, description="启动进程的环境变量。")

    enabled: bool = Field(default=True, description="该 MCP 服务是否启用。")
    tags: List[str] = Field(default_factory=list, description="MCP 服务标签列表。")
    extra: Optional[JSON] = Field(default=None, description="扩展配置数据。")


class McpResourceDescriptor(BaseModel):
    """MCP 资源描述。

    说明：
    - 可被 server/local 包装为 Tool（由上层决定）。
    - schema 字段用于描述输入输出，不代表实现细节。
    """

    id: str = Field(description="MCP 资源 ID。")
    server_id: str = Field(description="所属 MCP 服务 ID。")
    name: str = Field(description="MCP 资源名称。")
    description: Optional[str] = Field(default=None, description="MCP 资源描述。")
    input_schema: Optional[Dict[str, Any]] = Field(default=None, description="资源输入 Schema。")
    output_schema: Optional[Dict[str, Any]] = Field(default=None, description="资源输出 Schema。")
    extra: Optional[JSON] = Field(default=None, description="扩展资源元数据。")


class McpCallRequest(BaseModel):
    """对 MCP 资源的调用请求（协议 DTO）。"""

    server_id: str = Field(description="目标 MCP 服务 ID。")
    resource_id: str = Field(description="目标资源 ID。")
    method: str = Field(default="call", description="调用方法名，默认使用 call。")
    params: Optional[JSON] = Field(default=None, description="调用参数。")
    timeout_ms: Optional[int] = Field(default=None, description="调用超时时间，单位毫秒。")


class McpCallResult(BaseModel):
    """对 MCP 资源的调用结果（协议 DTO）。"""

    ok: bool = Field(description="调用是否成功。")
    result: Optional[JSON] = Field(default=None, description="调用成功时返回的结果数据。")
    error: Optional[str] = Field(default=None, description="调用失败时的错误信息。")
