# =============================================================================
# 企微IT智能服务台 — 管理后台 Pydantic Schema
# =============================================================================
# 说明：定义管理后台专用请求/响应数据结构
# 包含：仪表盘、配置管理、坐席管理、集成配置、快速回复审核、
#       分配模式、会话监控、全局搜索等全部 Schema
# =============================================================================

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

from pydantic import BaseModel, Field


# ==========================================================================
# 配置管理 Schema
# ==========================================================================

class ConfigItemResponse(BaseModel):
    """单个配置项响应 Schema。

    Attributes:
        key: 配置键
        value: 配置值
        description: 配置说明
        value_type: 值类型（boolean/number/string/json_array/json_object）
    """

    key: str = Field(..., description="配置键")
    value: str = Field(..., description="配置值")
    description: str = Field(default="", description="配置说明")
    value_type: str = Field(default="string", description="值类型: boolean/number/string/json_array/json_object")

    model_config = {"from_attributes": True}


class ConfigGroupResponse(BaseModel):
    """配置分组响应 Schema。

    按功能前缀将配置项分组，方便前端展示。

    Attributes:
        name: 分组名称
        key_prefix: 配置键前缀
        items: 该分组下的配置项列表
    """

    name: str = Field(..., description="分组名称")
    key_prefix: str = Field(..., description="配置键前缀")
    items: List[ConfigItemResponse] = Field(default_factory=list, description="配置项列表")


class ConfigUpdateRequest(BaseModel):
    """配置更新请求 Schema。

    Attributes:
        value: 新的配置值
    """

    value: str = Field(..., min_length=1, description="新的配置值")


class ConfigHistoryItem(BaseModel):
    """配置变更历史条目 Schema。

    Attributes:
        id: 日志ID
        config_key: 配置键
        old_value: 变更前的值
        new_value: 变更后的值
        changed_by: 变更操作人 agent_id
        changed_by_name: 变更操作人姓名
        changed_at: 变更时间
    """

    id: str = Field(..., description="日志ID")
    config_key: str = Field(..., description="配置键")
    old_value: str = Field(..., description="变更前的值")
    new_value: str = Field(..., description="变更后的值")
    changed_by: str = Field(..., description="变更操作人 agent_id")
    changed_by_name: str = Field(default="", description="变更操作人姓名")
    changed_at: datetime = Field(..., description="变更时间")

    model_config = {"from_attributes": True}


class ConfigHistoryResponse(BaseModel):
    """配置变更历史响应 Schema。

    Attributes:
        items: 变更历史条目列表
    """

    items: List[ConfigHistoryItem] = Field(default_factory=list, description="变更历史列表")


# ==========================================================================
# 坐席管理 Schema
# ==========================================================================

class AgentCreateRequest(BaseModel):
    """创建坐席请求 Schema。

    Attributes:
        user_id: 企微用户ID
        name: 坐席姓名
        role: 角色（admin=组长, agent=坐席）
        skill_tags: 技能标签列表
        max_load: 最大同时服务数
    """

    user_id: str = Field(..., min_length=1, max_length=64, description="企微用户ID")
    name: str = Field(..., min_length=1, max_length=128, description="坐席姓名")
    role: str = Field(default="agent", description="角色: admin=组长, agent=坐席")
    skill_tags: List[str] = Field(default_factory=list, description="技能标签列表")
    max_load: int = Field(default=5, ge=1, le=50, description="最大同时服务数")


class AgentUpdateRequest(BaseModel):
    """更新坐席请求 Schema。

    所有字段可选，只更新传入的字段。

    Attributes:
        role: 角色
        skill_tags: 技能标签列表
        max_load: 最大同时服务数
    """

    role: Optional[str] = Field(None, description="角色: admin=组长, agent=坐席")
    skill_tags: Optional[List[str]] = Field(None, description="技能标签列表")
    max_load: Optional[int] = Field(None, ge=1, le=50, description="最大同时服务数")


class AdminAgentResponse(BaseModel):
    """管理后台坐席响应 Schema（含角色/技能标签/今日结单数）。

    Attributes:
        id: 坐席ID
        user_id: 企微用户ID
        name: 坐席姓名
        status: 坐席状态
        role: 角色
        skill_tags: 技能标签列表
        current_load: 当前服务会话数
        max_load: 最大同时服务数
        today_resolved: 今日结单数
        created_at: 创建时间
        updated_at: 更新时间
    """

    id: str
    user_id: str
    name: str
    status: str
    role: str = "agent"
    skill_tags: List[str] = []
    current_load: int = 0
    max_load: int = 5
    today_resolved: int = 0
    otp_secret: Optional[str] = None
    otp_enabled: bool = False
    created_at: datetime
    updated_at: datetime

    model_config = {"from_attributes": True}


# =========================================================================
# 集成配置 Schema
# =========================================================================

class IntegrationConfig(BaseModel):
    """集成系统配置 Schema（通用，支持 url_key 和 access_key 两种模式）。

    Attributes:
        # url_key 模式（Dify / RAGFlow）
        api_url: API 地址
        api_key_set: API Key 是否已设置

        # access_key 模式（火绒安全）
        access_key_id_set: AccessKey ID 是否已设置
        access_key_secret_set: AccessKey Secret 是否已设置
        base_url: 内网 Base URL
    """
    # url_key 模式（Dify / RAGFlow）
    api_url: str = Field(default="", description="API 地址")
    api_key_set: bool = Field(default=False, description="API Key 是否已设置")

    # access_key 模式（火绒安全）
    access_key_id_set: bool = Field(default=False, description="AccessKey ID 是否已设置")
    access_key_secret_set: bool = Field(default=False, description="AccessKey Secret 是否已设置")
    base_url: Optional[str] = Field(default=None, description="内网 Base URL")

    # account_password 模式（联软LV7000）
    api_account_set: bool = Field(default=False, description="API账号是否已设置")
    api_password_set: bool = Field(default=False, description="API密码是否已设置")


class IntegrationResponse(BaseModel):
    """集成系统响应 Schema。

    Attributes:
        id: 集成系统ID（如 dify/ragflow/huorong）
        name: 集成系统名称
        status: 连接状态（connected/partial/disconnected/pending）
        configurable: 是否可配置
        config_type: 配置类型（url_key/access_key），前端据此显示不同表单
        config: 配置信息（不可配置时为 None）
    """

    id: str = Field(..., description="集成系统ID")
    name: str = Field(..., description="集成系统名称")
    status: str = Field(default="disconnected", description="连接状态: connected/partial/disconnected/pending")
    configurable: bool = Field(default=False, description="是否可配置")
    config_type: Optional[str] = Field(default=None, description="配置类型: url_key/access_key/account_password")
    config: Optional[IntegrationConfig] = Field(default=None, description="配置信息")


class IntegrationUpdateRequest(BaseModel):
    """集成系统配置更新请求 Schema。

    支持三种模式：
    - url_key 模式（Dify / RAGFlow）：传入 api_url + api_key
    - access_key 模式（火绒安全）：传入 access_key_id + access_key_secret + base_url
    - account_password 模式（联软LV7000）：传入 api_account + api_password + base_url + validate_key(可选)

    Attributes:
        # url_key 模式
        api_url: API 地址（可选，火绒/联软模式不需要）
        api_key: API Key（可选，火绒/联软模式不需要）

        # access_key 模式（火绒）
        access_key_id: AccessKey ID（可选）
        access_key_secret: AccessKey Secret（可选）
        base_url: 内网 Base URL（可选）

        # account_password 模式（联软）
        api_account: API账号（可选，联软模式）
        api_password: API密码（可选，联软模式）
        validate_key: 验证密钥（可选，联软模式）
    """

    # url_key 模式（Dify / RAGFlow）
    api_url: Optional[str] = Field(default=None, description="API 地址（Dify/RAGFlow 模式）")
    api_key: Optional[str] = Field(default=None, description="API Key（Dify/RAGFlow 模式）")

    # access_key 模式（火绒安全）
    access_key_id: Optional[str] = Field(default=None, description="AccessKey ID（火绒模式）")
    access_key_secret: Optional[str] = Field(default=None, description="AccessKey Secret（火绒模式）")
    base_url: Optional[str] = Field(default=None, description="内网 Base URL（火绒/联软模式）")

    # account_password 模式（联软LV7000）
    api_account: Optional[str] = Field(default=None, description="API账号（联软模式）")
    api_password: Optional[str] = Field(default=None, description="API密码（联软模式）")
    validate_key: Optional[str] = Field(default=None, description="验证密钥（联软模式，可选）")


# ==========================================================================
# 快速回复审核 Schema
# ==========================================================================

class QuickReplyReviewRequest(BaseModel):
    """快速回复审核请求 Schema。

    Attributes:
        action: 审核动作（approve=通过, reject=驳回）
        reason: 审核原因/意见（驳回时建议填写）
    """

    action: str = Field(..., description="审核动作: approve/reject")
    reason: str = Field(default="", description="审核原因/意见")


class AdminQuickReplyResponse(BaseModel):
    """管理后台快速回复响应 Schema（含审核信息）。

    Attributes:
        id: 模板ID
        category: 分类
        title: 模板标题
        content: 模板内容
        variables: 可用变量列表
        status: 状态
        version: 版本号
        submitted_by: 提交人 agent_id
        submitted_by_name: 提交人姓名
        sort_order: 排序权重
        created_at: 创建时间
        updated_at: 更新时间
    """

    id: str
    category: str
    title: str
    content: str
    variables: List[str]
    status: str = "approved"
    version: int = 1
    submitted_by: Optional[str] = None
    submitted_by_name: str = ""
    sort_order: int = 0
    created_at: datetime
    updated_at: datetime

    model_config = {"from_attributes": True}


# ==========================================================================
# 分配模式 Schema
# ==========================================================================

class AssignmentModeItem(BaseModel):
    """分配模式条目 Schema。

    Attributes:
        id: 模式ID
        name: 模式名称
        enabled: 是否启用
        locked: 是否锁定（阶段一锁定部分模式）
        unlock_at: 解锁阶段说明
    """

    id: str = Field(..., description="模式ID")
    name: str = Field(..., description="模式名称")
    enabled: bool = Field(default=False, description="是否启用")
    locked: bool = Field(default=True, description="是否锁定")
    unlock_at: str = Field(default="", description="解锁阶段说明")


class AssignmentModeResponse(BaseModel):
    """分配模式响应 Schema。

    Attributes:
        current_mode: 当前启用的分配模式
        modes: 所有分配模式列表
    """

    current_mode: str = Field(default="manual", description="当前分配模式")
    modes: List[AssignmentModeItem] = Field(default_factory=list, description="分配模式列表")


class AssignmentModeUpdateRequest(BaseModel):
    """分配模式更新请求 Schema。

    Attributes:
        mode: 要切换的分配模式ID
    """

    mode: str = Field(..., description="分配模式ID")


# ==========================================================================
# 仪表盘 Schema
# ==========================================================================

class SystemAlertItem(BaseModel):
    """单条系统告警 Schema。

    与前端 SystemAlert 接口对齐，支持结构化告警展示。

    Attributes:
        type: 告警类型（如 quick_reply_pending / agent_offline / system_error）
        content: 告警内容描述
        submitter: 提交人姓名（仅快速回复待审核类告警有值）
        time: 告警发生时间（ISO 8601 格式）
        severity: 严重程度（info/warning/critical）
    """

    type: str = Field(..., description="告警类型")
    content: str = Field(..., description="告警内容")
    submitter: Optional[str] = Field(default=None, description="提交人")
    time: str = Field(..., description="告警时间")
    severity: str = Field(default="info", description="严重程度: info/warning/critical")


class IntegrationHealthItem(BaseModel):
    """集成系统健康状态条目 Schema。

    Attributes:
        system: 系统名称
        status: 连接状态
    """

    system: str = Field(..., description="系统名称")
    status: str = Field(default="disconnected", description="连接状态")


class DashboardOverviewResponse(BaseModel):
    """仪表盘总览响应 Schema。

    Attributes:
        online_agents: 在线坐席数
        today_conversations: 今日会话数
        avg_response_time: 平均响应时间（阶段一占位）
        ai_hit_rate: AI 命中率（阶段一占位）
        pending_reviews: 待审核快速回复数
        system_alerts: 系统告警列表
        integrations_health: 集成系统健康状态
    """

    online_agents: int = Field(default=0, description="在线坐席数")
    today_conversations: int = Field(default=0, description="今日会话数")
    avg_response_time: str = Field(default="—", description="平均响应时间（阶段一占位）")
    ai_hit_rate: str = Field(default="—", description="AI命中率（阶段一占位）")
    pending_reviews: int = Field(default=0, description="待审核快速回复数")
    system_alerts: List[SystemAlertItem] = Field(default_factory=list, description="系统告警列表")
    integrations_health: List[IntegrationHealthItem] = Field(default_factory=list, description="集成系统健康状态")


# ==========================================================================
# 会话监控 Schema
# ==========================================================================

class SessionStats(BaseModel):
    """会话统计 Schema。

    Attributes:
        in_progress: 服务中会话数
        queued: 排队中会话数
        resolved_today: 今日已结单数
        alerts: 告警数
    """

    in_progress: int = Field(default=0, description="服务中会话数")
    queued: int = Field(default=0, description="排队中会话数")
    resolved_today: int = Field(default=0, description="今日已结单数")
    alerts: int = Field(default=0, description="告警数")


class SessionItem(BaseModel):
    """会话条目 Schema（监控列表用）。

    Attributes:
        id: 会话ID
        employee_name: 员工姓名
        status: 会话状态
        assigned_agent_name: 负责坐席姓名
        urgency_score: 紧急度评分
        created_at: 创建时间
        last_message_summary: 最后消息摘要
    """

    id: str = Field(..., description="会话ID")
    employee_name: str = Field(default="", description="员工姓名")
    status: str = Field(default="queued", description="会话状态")
    assigned_agent_name: str = Field(default="", description="负责坐席姓名")
    urgency_score: int = Field(default=1, description="紧急度评分")
    created_at: datetime = Field(..., description="创建时间")
    last_message_summary: str = Field(default="", description="最后消息摘要")


class MonitorSessionsResponse(BaseModel):
    """会话监控响应 Schema。

    Attributes:
        stats: 会话统计
        items: 会话列表
    """

    stats: SessionStats = Field(..., description="会话统计")
    items: List[SessionItem] = Field(default_factory=list, description="会话列表")


# ==========================================================================
# 全局搜索 Schema
# ==========================================================================

class SearchItem(BaseModel):
    """搜索结果条目 Schema。

    Attributes:
        type: 结果类型（config/agent/quick_reply）
        id: 对象ID
        name: 对象名称/标题
        route: 前端路由路径
    """

    type: str = Field(..., description="结果类型: config/agent/quick_reply")
    id: str = Field(..., description="对象ID")
    name: str = Field(..., description="对象名称/标题")
    route: str = Field(..., description="前端路由路径")


class SearchResponse(BaseModel):
    """搜索结果响应 Schema。

    Attributes:
        items: 搜索结果列表
    """

    items: List[SearchItem] = Field(default_factory=list, description="搜索结果列表")
