# -*- coding: utf-8 -*-
"""CN InfoHelpCommands 信息命令族（Phase 8 Tier 2）

借鉴 zhikuncode InfoHelpCommands.java（192 行）：
- /stats — 会话统计（消息数/工具调用数/文件修改数/持续时间）
- /advisor — AI 顾问模式（不直接改代码，只给建议）
- /btw — 顺便提问（不中断当前任务）
- /version — 版本信息（Python/abyss/OS）

集成点：main.py handle_slash_command 注册 4 条命令。
"""
import platform
import sys
import time
from collections import Counter
from typing import Dict, List, Any

# abyss 版本（懒加载避免循环导入）
_ABYSS_VERSION = None


def _get_abyss_version() -> str:
    """获取 abyss 版本号"""
    global _ABYSS_VERSION
    if _ABYSS_VERSION is None:
        try:
            from abyss import __version__
            _ABYSS_VERSION = __version__
        except (ImportError, AttributeError):
            _ABYSS_VERSION = "unknown"
    return _ABYSS_VERSION


def count_messages_by_role(messages: List[Dict[str, Any]]) -> Dict[str, int]:
    """按 role 统计消息数。

    Args:
        messages: 会话消息列表

    Returns:
        {role: count} 字典
    """
    counter: Counter = Counter()
    for msg in messages:
        if isinstance(msg, dict):
            role = msg.get("role", "unknown")
            counter[role] += 1
    return dict(counter)


def count_tool_calls(messages: List[Dict[str, Any]]) -> int:
    """统计 tool_calls 总数。

    Args:
        messages: 会话消息列表

    Returns:
        tool_calls 总数
    """
    total = 0
    for msg in messages:
        if not isinstance(msg, dict):
            continue
        if msg.get("role") != "assistant":
            continue
        tool_calls = msg.get("tool_calls") or []
        if isinstance(tool_calls, list):
            total += len(tool_calls)
    return total


def format_duration(seconds: float) -> str:
    """格式化时长为人类可读字符串。

    Args:
        seconds: 秒数

    Returns:
        "Xh Ym Zs" / "Ym Zs" / "Zs"
    """
    if seconds < 0:
        return "0s"
    seconds = int(seconds)
    hours, rem = divmod(seconds, 3600)
    minutes, secs = divmod(rem, 60)
    if hours > 0:
        return f"{hours}h {minutes}m {secs}s"
    if minutes > 0:
        return f"{minutes}m {secs}s"
    return f"{secs}s"


def handle_stats(session) -> str:
    """/stats 命令处理：显示会话统计信息。

    Args:
        session: Session 实例，需有 messages 属性

    Returns:
        可读的统计信息字符串
    """
    messages = getattr(session, "messages", [])
    role_counts = count_messages_by_role(messages)
    tool_call_count = count_tool_calls(messages)

    # 计算持续时间
    started_at = getattr(session, "started_at", None)
    if started_at:
        try:
            duration = time.time() - float(started_at)
            duration_str = format_duration(duration)
        except (TypeError, ValueError):
            duration_str = "未知"
    else:
        duration_str = "未知"

    lines = [
        "📊 会话统计",
        "",
        f"消息总数: {len(messages)}",
        f"  - system: {role_counts.get('system', 0)}",
        f"  - user: {role_counts.get('user', 0)}",
        f"  - assistant: {role_counts.get('assistant', 0)}",
        f"  - tool: {role_counts.get('tool', 0)}",
        f"工具调用次数: {tool_call_count}",
        f"持续时间: {duration_str}",
    ]

    # 工具使用统计（从 metrics 日志读取）
    try:
        from .logs import _read_jsonl, _compute_stats
        from ..logger import LOG_DIR
        from datetime import datetime as _dt
        today = _dt.now().strftime("%Y-%m-%d")
        metrics_fp = LOG_DIR / f"metrics_{today}.jsonl"
        records = _read_jsonl(metrics_fp)
        if records:
            lines.append("")
            lines.append(_compute_stats(records))
    except Exception:
        pass  # 统计失败不影响主流程

    return "\n".join(lines)


# Advisor Prompt：顾问模式（不直接改代码）
ADVISOR_PROMPT = """# Advisor 顾问模式

你现在是 Advisor 顾问模式。请遵守以下规则：

## 严格规则

1. **不直接修改代码**：你只能给出建议和方案，不调用任何 file_edit/file_write 工具
2. **不执行命令**：不调用 shell_exec 工具，可调用 file_read 只读分析
3. **给出方案而非实现**：描述思路、伪代码、改动位置，但不写完整实现
4. **解释利弊**：对每个建议给出 pros/cons，让用户自己决策
5. **引用文档**：如适用，引用官方文档或最佳实践

## 文件读取节制（重要）

- **总 file_read 调用次数不超过 8 次**。先列出 2-3 个关键入口文件（如 main.py / pyproject.toml / package.json），基于已知信息分析。
- **不要逐个尝试读取项目所有模块**。先读最关键的 1-3 个入口文件，给出基于初步信息的分析。
- **不确定路径时不要猜测**。若用户提到的文件路径不存在，直接说明并建议用户给出正确路径，不要试探。
- 用户问"整体架构"时，只读 main.py + 包结构 manifest（pyproject.toml / setup.py / package.json）就够了。

## 输出格式

对每个建议：
- **方案**：一句话描述
- **改动位置**：文件路径 + 函数名
- **改动思路**：3-5 步描述
- **优点**：3 条
- **缺点 / 风险**：2 条
- **替代方案**：1-2 个备选

---
"""


def handle_advisor(session, user_desc: str) -> str:
    """/advisor 命令处理：注入顾问模式 prompt。

    Args:
        session: Session 实例
        user_desc: 用户描述的咨询问题

    Returns:
        "injected" 或错误消息
    """
    if not user_desc.strip():
        return "用法: /advisor <你的咨询问题>"

    combined = f"{ADVISOR_PROMPT}\n---\n\n# 用户咨询\n{user_desc}"
    session.add_user(combined)
    return "injected"


# BTW Prompt：顺便提问（不中断当前任务）
BTW_PROMPT = """# BTW 顺便提问模式

用户在执行主任务时顺便插入一个简短问题。请遵守：

## 严格规则

1. **简短回答**：用 1-3 段话回答，不展开长篇大论
2. **不偏离主任务**：不要尝试接管主任务，只回答这个顺便的问题
3. **不调用工具**：除非用户明确要求查文件，否则直接基于现有知识回答
4. **标注继续**：回答完后提示用户"已回答顺便问题，继续主任务"

---
"""


def handle_btw(session, user_desc: str) -> str:
    """/btw 命令处理：注入顺便提问 prompt。

    Args:
        session: Session 实例
        user_desc: 顺便提问的内容

    Returns:
        "injected" 或错误消息
    """
    if not user_desc.strip():
        return "用法: /btw <你的问题>"

    combined = f"{BTW_PROMPT}\n---\n\n# 顺便提问\n{user_desc}"
    session.add_user(combined)
    return "injected"


def handle_version() -> str:
    """/version 命令处理：显示版本信息。

    Returns:
        版本信息字符串
    """
    lines = [
        "📋 版本信息",
        "",
        f"abyss: {_get_abyss_version()}",
        f"Python: {platform.python_version()}",
        f"Platform: {platform.system()} {platform.release()} ({platform.machine()})",
        f"Implementation: {platform.python_implementation()}",
    ]
    return "\n".join(lines)
