"""
腾讯会议连接器工具 (tencent_meeting_tool.py) — v2

重要设计：
  ┌─────────────────────────────────────────────────────┐
  │  绑定流程：侧边栏 inline UI（链接 + Token 粘贴）      │
  │  调用流程：SKILL.md + Agent 对话                     │
  └─────────────────────────────────────────────────────┘
  两条路径完全隔离，互不依赖。

Token 存储（per-user JSON，优先于全局 env var）：
  /opt/apps/mindos-next/backend/data/tencent_meeting_tokens.json
  格式：{ "userId": "HpLzd..." }

注意：腾讯会议目前仅支持「个人账号」认证。
  Token 获取地址：https://meeting.tencent.com/ai-skill.html
"""

import json
import logging
import os
import subprocess
from pathlib import Path
from typing import Any, Dict, Optional

from tools.registry import registry, tool_error, tool_result

logger = logging.getLogger(__name__)

# ── 腾讯会议脚本路径（候选列表，取第一个存在的）──
_SCRIPT_CANDIDATES = [
    Path("/root/hermess/skills/tencent-meeting/scripts/tencent_meeting.py"),
    Path("/Users/lidongfang/Downloads/Coding/hermess/skills/tencent-meeting/scripts/tencent_meeting.py"),
]

# ── Per-user Token 存储（wiki/{userId}/.config/tencent_meeting.json） ──
from tools._user_config import user_config_read, user_config_write, user_config_delete

# ── 腾讯会议 Token 获取地址（仅个人账号） ──
TOKEN_OBTAIN_URL = "https://meeting.tencent.com/ai-skill.html"


# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Token 存取（per-user）
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

def get_user_token(user_id: str) -> str:
    """
    获取指定用户的 Token。
    优先：per-user 存储 → 兜底：全局 env var（向后兼容）
    """
    config = user_config_read(user_id, "tencent_meeting")
    token = config.get("token", "").strip()
    if token:
        return token
    # 兜底：全局 env（管理员配置场景）
    return os.environ.get("TENCENT_MEETING_TOKEN", "").strip()


def set_user_token(user_id: str, token: str) -> None:
    """保存或清除指定用户的 Token。token 为空则删除条目。"""
    token = token.strip()
    if token:
        user_config_write(user_id, "tencent_meeting", {"token": token})
    else:
        user_config_delete(user_id, "tencent_meeting")


def has_user_token(user_id: str) -> bool:
    return bool(get_user_token(user_id))


# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 脚本路径 & 可用性检查
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

def _get_script_path() -> Optional[Path]:
    for p in _SCRIPT_CANDIDATES:
        if p.exists():
            return p
    return None


def _check_tencent_meeting() -> bool:
    """可用性检查：脚本存在即可（Token 在 handler 中按用户检查）。"""
    return bool(_get_script_path())


# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 子进程抽象层（同步，线程安全）
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

def _run_tencent_meeting(
    tool_name: str,
    arguments: Dict[str, Any],
    user_id: str = "",
    timeout: int = 30,
) -> tuple:
    """
    同步调用 tencent_meeting.py tools/call。
    user_id 用于查找 per-user Token。
    返回 (stdout: str, stderr: str, returncode: int)
    """
    script = _get_script_path()
    if not script:
        return "", "找不到 tencent_meeting.py 脚本，请检查部署配置", -2

    token = get_user_token(user_id) if user_id else os.environ.get("TENCENT_MEETING_TOKEN", "")
    if not token:
        return "", "腾讯会议 Token 未配置。请在侧边栏绑定账号。", -4

    arguments.setdefault("_client_info", {
        "os": "linux",
        "agent": "mindos",
        "model": "gemini",
    })

    params_json = json.dumps({"name": tool_name, "arguments": arguments}, ensure_ascii=False)
    cmd = ["python3", str(script), "tools/call", params_json]
    logger.info("[TencentMeetingTool] exec: tools/call %s (user=%s)", tool_name, user_id[:8] if user_id else "global")

    env = os.environ.copy()
    env["TENCENT_MEETING_TOKEN"] = token   # 注入到子进程

    try:
        r = subprocess.run(
            cmd,
            capture_output=True,
            timeout=timeout,
            text=True,
            env=env,
            cwd=str(script.parent),
        )
        return r.stdout.strip(), r.stderr.strip(), r.returncode
    except subprocess.TimeoutExpired:
        return "", f"命令超时（{timeout}s）", -1
    except FileNotFoundError:
        return "", "python3 未找到", -3


# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# ① tencent_meeting_list_profiles
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

def _tencent_meeting_list_profiles_handler(args: dict, **kwargs) -> str:
    user_id = str(args.get("user_id", "")).strip()
    if not user_id:
        return tool_error("user_id 参数必填")

    token_exists = has_user_token(user_id)

    if not token_exists:
        return tool_result(
            success=True,
            profiles=[],
            count=0,
            tokenConfigured=False,
            tokenObtainUrl=TOKEN_OBTAIN_URL,
            notice="腾讯会议目前仅支持个人账号认证。请前往上述链接获取 Token 并在侧边栏绑定。",
        )

    script = _get_script_path()
    if not script:
        return tool_result(
            success=True,
            profiles=[],
            count=0,
            tokenConfigured=True,
            message="腾讯会议脚本未找到，请检查服务器部署。",
        )

    # 用 convert_timestamp 验证连通性
    stdout, stderr, rc = _run_tencent_meeting("convert_timestamp", {}, user_id=user_id, timeout=15)
    status  = "connected" if rc == 0 else "error"
    message = "腾讯会议已连接。" if rc == 0 else f"连接异常：{(stderr or stdout)[:120]}"

    profiles = [{
        "profileName": f"{user_id[:12]}_tencent",
        "label": "腾讯会议",
        "status": status,
        "tokenConfigured": True,
        "notice": "腾讯会议目前仅支持个人账号认证。",
    }]

    return tool_result(
        success=True,
        profiles=profiles,
        count=len(profiles),
        tokenConfigured=True,
        message=message,
    )


registry.register(
    name="tencent_meeting_list_profiles",
    toolset="connectors",
    description="检查腾讯会议连接状态，返回账号信息。",
    emoji="📋",
    check_fn=_check_tencent_meeting,
    handler=_tencent_meeting_list_profiles_handler,
    schema={
        "name": "tencent_meeting_list_profiles",
        "description": "检查腾讯会议是否已连接，返回连接状态。",
        "parameters": {
            "type": "object",
            "properties": {
                "user_id": {"type": "string", "description": "MINDOS_USER_ID"},
            },
            "required": ["user_id"],
        },
    },
)


# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# ② tencent_meeting_query（白名单操作）
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

_ALLOWED_TOOLS = {
    "convert_timestamp",
    "schedule_meeting",
    "get_meeting_by_code",
    "get_meeting",
    "get_user_meetings",
    "get_user_ended_meetings",
    "get_smart_minutes",
    "get_records_list",
}


def _tencent_meeting_query_handler(args: dict, **kwargs) -> str:
    user_id   = str(args.get("user_id", "")).strip()
    tool_name = str(args.get("tool_name", "")).strip()

    if not user_id:
        return tool_error("user_id 参数必填")
    if not tool_name:
        return tool_error("tool_name 参数必填")
    if tool_name not in _ALLOWED_TOOLS:
        return tool_error(
            f"不支持的工具：{tool_name}。可选：{', '.join(sorted(_ALLOWED_TOOLS))}"
        )
    if not has_user_token(user_id):
        return tool_error(
            f"腾讯会议 Token 未配置。请前往 {TOKEN_OBTAIN_URL} 获取 Token，"
            "并在侧边栏「腾讯会议」处绑定账号。"
        )

    arguments = args.get("arguments", {})
    if not isinstance(arguments, dict):
        return tool_error("arguments 必须是 JSON 对象")

    stdout, stderr, rc = _run_tencent_meeting(tool_name, arguments, user_id=user_id, timeout=30)

    if rc != 0:
        return tool_error(f"调用失败（exit {rc}）：{(stderr or stdout)[:300]}")
    if not stdout:
        return tool_error(f"无输出。stderr: {stderr[:200]}")

    try:
        data = json.loads(stdout)
        return tool_result(success=True, data=data)
    except (json.JSONDecodeError, ValueError):
        return tool_result(success=True, output=stdout[:3000])


registry.register(
    name="tencent_meeting_query",
    toolset="connectors",
    description="执行腾讯会议数据查询（会议列表/纪要/录制等）。",
    emoji="📹",
    check_fn=_check_tencent_meeting,
    handler=_tencent_meeting_query_handler,
    schema={
        "name": "tencent_meeting_query",
        "description": (
            "调用腾讯会议 MCP 工具。需先在侧边栏完成 Token 绑定。\n"
            "示例：\n"
            "  查当前时间: tool_name=convert_timestamp, arguments={}\n"
            "  查未来会议: tool_name=get_user_meetings, arguments={\"pos\": <unix_ts>}\n"
            "  查 AI 纪要: tool_name=get_smart_minutes, arguments={\"meeting_id\": \"xxx\"}\n"
            "  预约会议:   tool_name=schedule_meeting, arguments={\"subject\":\"xx\",\"start_time\":\"...\",\"end_time\":\"...\"}\n"
        ),
        "parameters": {
            "type": "object",
            "properties": {
                "user_id": {"type": "string", "description": "MINDOS_USER_ID"},
                "tool_name": {
                    "type": "string",
                    "description": "腾讯会议工具名",
                    "enum": sorted(_ALLOWED_TOOLS),
                },
                "arguments": {
                    "type": "object",
                    "description": "工具参数（_client_info 由工具自动注入，不需要传）",
                },
            },
            "required": ["user_id", "tool_name"],
        },
    },
)
