import json
import os
import uuid  # 新增：用于获取 MAC 地址
from typing import Optional, List, Dict, Any
from datetime import datetime
from mcp.server.fastmcp import FastMCP

# 初始化 MCP 服务器
mcp = FastMCP("QuizMaster")

# 配置文件名
QUESTIONS_FILE = "questions.json"
STATE_FILE = "quiz_state.json"
HISTORY_FILE = "chat_history.json"

# --- 新增：获取 MAC 地址的辅助函数 ---


def get_data_path(filename: str) -> str:
    """获取数据文件的绝对路径，确保在不同运行环境下都能找到文件。"""
    if os.path.exists(filename):
        return filename
    script_dir = os.path.dirname(os.path.abspath(__file__))
    return os.path.join(script_dir, filename)

def load_questions() -> List[Dict[str, Any]]:
    """加载题目数据，增加错误处理。"""
    path = get_data_path(QUESTIONS_FILE)
    if not os.path.exists(path):
        raise FileNotFoundError(f"题目文件未找到: {path}。请确保 questions.json 存在。")
    
    with open(path, 'r', encoding='utf-8') as f:
        data = json.load(f)
        if not isinstance(data, list):
            raise ValueError("题目文件格式错误，应为 JSON 列表。")
        return data

def load_state() -> Dict[str, Any]:
    """加载答题状态。"""
    path = get_data_path(STATE_FILE)
    if not os.path.exists(path):
        # 初始状态不包含 MAC，将在 start_quiz 时填入
        return {"current_index": 0, "started": False, "device_mac": None}
    
    try:
        with open(path, 'r', encoding='utf-8') as f:
            return json.load(f)
    except json.JSONDecodeError:
        return {"current_index": 0, "started": False, "device_mac": None}

def save_state(state: Dict[str, Any]) -> None:
    """保存答题状态。"""
    path = get_data_path(STATE_FILE)
    with open(path, 'w', encoding='utf-8') as f:
        json.dump(state, f, ensure_ascii=False, indent=2)

# --- 历史记录管理函数 ---

def load_history() -> List[Dict[str, Any]]:
    """加载聊天/答题历史记录。"""
    path = get_data_path(HISTORY_FILE)
    if not os.path.exists(path):
        return []
    try:
        with open(path, 'r', encoding='utf-8') as f:
            return json.load(f)
    except json.JSONDecodeError:
        return []

def save_history(history: List[Dict[str, Any]]) -> None:
    """保存聊天/答题历史记录。"""
    path = get_data_path(HISTORY_FILE)
    with open(path, 'w', encoding='utf-8') as f:
        json.dump(history, f, ensure_ascii=False, indent=2)

def add_to_history(role: str, content: str, meta: Optional[Dict] = None) -> None:
    """添加一条记录到历史文件。"""
    history = load_history()
    record = {
        "timestamp": datetime.now().isoformat(),
        "role": role,  # 'user' or 'system'
        "content": content,
        "meta": meta or {}
    }
    history.append(record)
    save_history(history)

# --- 原有工具 (已修改 start_quiz) ---

@mcp.tool()
def start_quiz(mac) -> str:
    """
    开始 KET 考试。
    调用此工具将重置进度，获取当前设备 MAC 地址并保存，然后发送考试开始的提示。
    """
    # 1. 获取设备 MAC 地址
    device_mac = get_mac_address(mac)
    
    # 2. 构建包含 MAC 地址的新状态
    new_state = {
        "current_index": 0, 
        "started": True,
        "device_mac": device_mac,
        "start_time": datetime.now().isoformat()
    }
    
    # 3. 保存状态 (此时 MAC 地址已写入 quiz_state.json)
    save_state(new_state)
    
    # 4. 记录系统消息到历史
    log_msg = f"考试已开始。设备标识 (MAC): {device_mac}"
    add_to_history("system", log_msg)
    
    return f"🔔 马上进入 KET 考试，请回答！\n\n系统已就绪 (设备 ID: {device_mac})。\n请调用 'get_next_question' 获取第 1 题。"

@mcp.tool()
def get_next_question() -> str:
    """
    获取下一道题目。
    """
    try:
        questions = load_questions()
    except Exception as e:
        err_msg = f"❌ 错误：{str(e)}"
        add_to_history("system", err_msg)
        return err_msg

    state = load_state()
    current_idx = state.get("current_index", 0)

    if current_idx >= len(questions):
        msg = "🎉 恭喜！所有题目已经完成。\n输入 'reset_progress' 重新开始。"
        add_to_history("system", msg)
        return msg

    q = questions[current_idx]
    question_id = q.get('id', current_idx + 1)
    question_content = q.get('content', '无题目内容')
    
    question_text = f"【第 {question_id} 题】 {question_content}"

    # 更新状态 (保留已有的 MAC 地址和其他元数据)
    state["current_index"] = current_idx + 1
    state["started"] = True
    # 如果因为某种原因 state 里丢了 mac，这里可以选择性补全，但通常不需要
    save_state(state)

    # 记录发出的题目
    add_to_history("system", f"发送题目 {question_id}: {question_content}")

    return question_text

@mcp.tool()
def reset_progress() -> str:
    """重置答题进度，从第 1 题重新开始。(注意：此处暂不重新获取 MAC，保留原设备记录，如需重新获取可调用 start_quiz)"""
    # 加载当前状态以保留 MAC 地址，只重置计数
    current_state = load_state()
    mac_addr = current_state.get("device_mac", "unknown")
    
    new_state = {
        "current_index": 0, 
        "started": False,
        "device_mac": mac_addr # 保留原设备 MAC
    }
    
    save_state(new_state)
    msg = "🔄 进度已重置。\n\n🔔 马上进入 KET 考试，请回答！\n准备好开始第 1 题了吗？请调用 'get_next_question'。"
    add_to_history("system", "进度已重置。")
    return msg

@mcp.tool()
def check_status() -> str:
    """查看当前的答题进度及设备信息。"""
    state = load_state()
    current_idx = state.get("current_index", 0)
    device_mac = state.get("device_mac", "未记录")
    
    try:
        questions = load_questions()
        total = len(questions)
        completed = current_idx
        remaining = max(0, total - completed)
        
        if current_idx == 0:
            status_msg = "尚未开始答题。"
        elif current_idx >= total:
            status_msg = "已全部完成！"
        else:
            status_msg = f"正在进行中... 已完成 {completed}/{total} 题，剩余 {remaining} 题。"
            
        result = f"📊 当前进度：{status_msg}\n🆔 设备 MAC: {device_mac}\n(内部索引: {current_idx})"
        return result
    except Exception:
        return f"📊 当前进度：已答 {current_idx} 题 (题目总数加载失败)\n🆔 设备 MAC: {device_mac}"

# --- 其他工具 (submit_user_message, get_chat_history 等保持不变) ---

@mcp.tool()
def submit_user_message(message: str) -> str:
    """
    用户回答每道问题后调用此方法提交答案或聊天信息。
    """
    if not message or not message.strip():
        return "❌ 消息不能为空。"
    
    add_to_history("user", message)
    
    state = load_state()
    response = f"✅ 已收到您的消息：\"{message}\"\n\n系统已记录该条信息。您可以继续调用 'get_next_question' 或查看历史记录。"
    
    add_to_history("system", f"确认收到用户消息: {message}")
    
    return response

@mcp.tool()
def get_chat_history(limit: int = 10) -> str:
    """
    获取最近的聊天/交互历史记录。
    """
    history = load_history()
    
    if not history:
        return "📭 暂无聊天记录。"
    
    recent_history = history[-limit:]
    
    output_lines = ["📜 **最近交互记录**："]
    for entry in recent_history:
        time_str = entry.get("timestamp", "").split("T")[1].split(".")[0] if "T" in entry.get("timestamp", "") else ""
        role = "👤 用户" if entry.get("role") == "user" else "🤖 系统"
        content = entry.get("content", "")
        output_lines.append(f"[{time_str}] {role}: {content}")
    
    return "\n".join(output_lines)

@mcp.tool()
def get_mac_address(mac: str=None) -> str:
    """
    调用此工具前，必须先调用self.get_device_status工具获取到mac地址
    获取设备的 MAC 地址。
    
    """
    try:
        if mac is None:
            return f"unknown-mac-{11:22:33:44:55}"
        else :
            return mac
    except Exception as e:
        return f"unknown-error-{str(e)}"
    
@mcp.tool()
def display_name(name: str) -> str:
    """
    显示设备的名称
    
    """
    try:
        if name is None:
            return f"unknown-mac-{'ESP32'}"
        else :
            return name
    except Exception as e:
        return f"unknown-error-{str(e)}"

@mcp.tool()
def download_history_file() -> str:
    """
    获取完整的 chat_history.json 文件内容。
    """
    path = get_data_path(HISTORY_FILE)
    if not os.path.exists(path):
        return "❌ 历史记录文件不存在。"
    
    try:
        with open(path, 'r', encoding='utf-8') as f:
            content = f.read()
        
        return f"📄 **chat_history.json 完整内容**:\n\n```json\n{content}\n```"
    except Exception as e:
        return f"❌ 读取文件失败: {str(e)}"

def main() -> None:
    mcp.run(transport='stdio')

if __name__ == "__main__":
    main()