# -*- coding: utf-8 -*-
"""
会话管理接口 —— 聊天历史查询、会话列表、删除会话、权限模式管理
"""

from fastapi import APIRouter, Depends
from pydantic import BaseModel, Field

from api.auth import get_current_user
from db.chat_store import (
    get_messages, get_sessions, delete_session,
    get_session_mode, set_session_mode, get_latest_context_usage,
    pin_session, is_session_pinned, update_session_title,
    search_sessions,
)

router = APIRouter()


class ModeRequest(BaseModel):
    """权限模式切换请求"""
    mode: str = Field(..., description="权限模式", examples=["plan", "full"])


class TitleRequest(BaseModel):
    """会话标题编辑请求"""
    title: str = Field(..., description="新标题", max_length=100, examples=["15216工作面需风量计算"])


@router.get("/chat/history/{session_id}")
async def get_chat_history(
    session_id: str,
    limit: int = 100,
    offset: int = 0,
    user_info: dict = Depends(get_current_user),
):
    """查询指定会话的聊天历史

    Args:
        session_id: 会话ID
        limit: 返回条数上限，默认100
        offset: 偏移量，默认0

    Returns:
        { "session_id": "...", "messages": [...], "total": N }
    """
    messages = get_messages(session_id, limit=limit, offset=offset)

    # 计算总数
    all_msgs = get_messages(session_id, limit=10000)
    total = len(all_msgs)

    return {
        "session_id": session_id,
        "messages": messages,
        "total": total,
    }


@router.get("/sessions")
async def list_sessions(
    limit: int = 20,
    offset: int = 0,
    user_info: dict = Depends(get_current_user),
):
    """查询当前用户的会话列表（按更新时间倒序）

    Returns:
        [{ "session_id": "...", "title": "...", "message_count": N, ... }, ...]
    """
    user_name = user_info.get("username", "admin")
    sessions = get_sessions(limit=limit, offset=offset, user_name=user_name)
    return {"sessions": sessions, "total": len(sessions)}


@router.get("/sessions/search")
async def search_session_titles(
    q: str = "",
    limit: int = 10,
    user_info: dict = Depends(get_current_user),
):
    """按标题模糊搜索当前用户的会话（用于插入会话功能）。

    Args:
        q: 搜索关键词（匹配会话标题）
        limit: 最大返回条数，默认 10

    Returns:
        { "sessions": [...], "total": N }
    """
    user_name = user_info.get("username", "admin")
    if not q or not q.strip():
        # 无关键词时返回最近会话
        sessions = get_sessions(limit=limit, offset=0, user_name=user_name)
        return {"sessions": sessions, "total": len(sessions)}
    sessions = search_sessions(user_name, q.strip(), limit=limit)
    return {"sessions": sessions, "total": len(sessions)}


@router.delete("/sessions/{session_id}")
async def remove_session(
    session_id: str,
    user_info: dict = Depends(get_current_user),
):
    """删除指定会话及其所有消息"""
    delete_session(session_id)
    return {"status": "ok", "message": f"会话 {session_id} 已删除"}


# ── 权限模式管理 ──

@router.get("/sessions/{session_id}/mode")
async def get_mode(
    session_id: str,
    user_info: dict = Depends(get_current_user),
):
    """获取会话的权限模式"""
    return {
        "session_id": session_id,
        "mode": get_session_mode(session_id),
    }


@router.put("/sessions/{session_id}/mode")
async def set_mode(
    session_id: str,
    req: ModeRequest,
    user_info: dict = Depends(get_current_user),
):
    """设置会话的权限模式

    mode 取值：
    - plan:    计划模式（先生成执行计划，用户确认后再执行）
    - full:    完全访问（无限制自动执行）
    """
    valid = {"plan", "full"}
    if req.mode not in valid:
        return {
            "error": f"无效的模式: {req.mode}",
            "valid_modes": sorted(valid),
        }

    set_session_mode(session_id, req.mode)
    return {
        "session_id": session_id,
        "mode": req.mode,
        "message": f"已切换为「{req.mode}」模式",
    }


# ── 会话置顶 ──

@router.put("/sessions/{session_id}/pin")
async def toggle_pin(
    session_id: str,
    user_info: dict = Depends(get_current_user),
):
    """切换会话置顶状态（置顶 ⇄ 取消置顶）。

    Returns:
        { "session_id": "...", "pinned": true, "message": "..." }
    """
    pinned = not is_session_pinned(session_id)
    pin_session(session_id, pinned)
    return {
        "session_id": session_id,
        "pinned": pinned,
        "message": "已置顶" if pinned else "已取消置顶",
    }


# ── 会话标题编辑 ──

@router.put("/sessions/{session_id}/title")
async def edit_title(
    session_id: str,
    req: TitleRequest,
    user_info: dict = Depends(get_current_user),
):
    """编辑会话标题。

    Args:
        req.title: 新标题，最长100字
    """
    title = req.title.strip()
    if not title:
        return {"error": "标题不能为空"}
    if len(title) > 100:
        return {"error": f"标题过长（{len(title)}字），最多100字"}

    update_session_title(session_id, title)
    return {
        "session_id": session_id,
        "title": title,
        "message": "标题已更新",
    }


# ── 上下文容量查询 ──

@router.get("/sessions/{session_id}/context")
async def get_context_usage(
    session_id: str,
    user_info: dict = Depends(get_current_user),
):
    """查询会话最近一次的上下文用量详情。

    Returns:
        {
            "session_id": "...",
            "total_limit": 131072,
            "current_usage": 12345,
            "usage_pct": 9.4,
            "breakdown": {
                "messages": 5000,
                "mcp": 4000,
                "skills": 800,
                "system_prompt": 600,
                "other": 2745
            },
            "updated_at": "2026-08-05 14:30:00"
        }
        若无记录则返回 null 值。
    """
    row = get_latest_context_usage(session_id)
    if not row:
        return {
            "session_id": session_id,
            "total_limit": None,
            "current_usage": None,
            "usage_pct": None,
            "breakdown": None,
            "updated_at": None,
        }

    total_limit = row.get("total_limit", 131072)
    current = row.get("current_usage", 0)
    pct = round(current / total_limit * 100, 1) if total_limit else 0

    return {
        "session_id": session_id,
        "total_limit": total_limit,
        "current_usage": current,
        "usage_pct": pct,
        "breakdown": {
            "messages": row.get("messages_tokens", 0),
            "mcp": row.get("mcp_tokens", 0),
            "skills": row.get("skills_tokens", 0),
            "system_prompt": row.get("system_prompt_tokens", 0),
            "other": row.get("other_tokens", 0),
        },
        "updated_at": row.get("updated_at"),
    }
