# agents/vibe_learning_agent.py
"""互动学习 Agent - 通过对话和测验巩固知识"""

import json
from datetime import datetime
from typing import Dict, List
from hello_agents import HelloAgentsLLM
from hello_agents import SimpleAgent
from specialist.quiz_generator import QuizGeneratorAgent
from core.file_manager import FileManager
from core.summary_manager import SummaryManager


class VibeLearningAgent(SimpleAgent):
    """
    互动学习专家

    功能：
    - 支持两种模式：free（自由对话）和 quiz（结构化测验）
    - 根据学习计划生成问题
    - 评估用户回答并提供反馈
    - 动态调整问题难度
    - 生成会话总结
    """

    def __init__(self, llm: HelloAgentsLLM, file_manager: FileManager, streaming: bool = None):
        """
        初始化 VibeLearningAgent

        Args:
            llm: HelloAgentsLLM 实例
            file_manager: FileManager 实例
            streaming: 是否启用流式输出（None = 自动检测）
        """
        system_prompt = """
你是专业的学习教练。

工作流程：
1. 读取学习计划（plan.md），了解知识体系
2. 根据模式（free/quiz）生成初始问题
3. 评估用户回答，给予反馈
4. 动态调整问题难度
5. 结束时生成会话总结

模式差异：
- free: 开放性问题，鼓励讨论，引导思考
- quiz: 结构化考察，固定问题，自动评分

反馈技巧：
- 肯定正确的部分
- 指出需要改进的地方
- 提供额外的知识点链接
- 鼓励继续探索
"""

        self.llm = llm
        self.file_manager = file_manager
        self.quiz_generator = QuizGeneratorAgent(llm)
        self.max_iterations = 10

        # 添加流式输出支持
        from utils.streaming import should_stream
        self.streaming = should_stream(streaming)

        # 使用父类初始化
        super().__init__("VibeLearningAgent", llm, system_prompt)

    def start_session(
        self, domain: str, mode: str = "free"
    ) -> str:
        """
        开始互动学习会话（只生成第一个问题）

        Args:
            domain: 领域名称
            mode: 学习模式（free/quiz）

        Returns:
            第一个问题
        """
        # 检查领域是否存在
        if not self.file_manager.domain_exists(domain):
            return f"❌ 领域 '{domain}' 不存在。请先使用 /create 创建学习计划。"

        # 读取学习计划
        try:
            plan = self.file_manager.read_plan(domain)
        except Exception as e:
            return f"❌ 读取学习计划失败：{e}"

        # 生成第一个问题
        question = self._generate_first_question(plan, mode)

        # 保存问题到会话历史（用于后续继续）
        self._save_session_start(domain, mode, question)

        return f"""💬 {mode.upper()} 模式学习会话开始

{question}

💡 提示：输入你的回答开始对话
"""

    def _save_session_start(self, domain: str, mode: str, question: str) -> None:
        """
        保存会话开始状态

        Args:
            domain: 领域名称
            mode: 模式
            question: 第一个问题
        """
        session_path = self.file_manager.BASE_DIR / domain / "sessions"
        session_path.mkdir(parents=True, exist_ok=True)

        # 创建临时会话文件
        temp_file = session_path / ".current_session.txt"
        temp_file.write_text(
            f"{mode}\n{datetime.now().strftime('%Y-%m-%d %H:%M')}\n{question}",
            encoding='utf-8'
        )

    def continue_session(self, domain: str, user_answer: str, mode: str) -> str:
        """
        继续对话会话

        Args:
            domain: 领域名称
            user_answer: 用户回答
            mode: 模式

        Returns:
            反馈和下一个问题
        """
        try:
            # 读取计划
            plan = self.file_manager.read_plan(domain)

            # 读取上一个问题（从临时文件）
            session_path = self.file_manager.BASE_DIR / domain / "sessions"
            temp_file = session_path / ".current_session.txt"

            if temp_file.exists():
                lines = temp_file.read_text(encoding='utf-8').strip().split('\n')
                last_question = lines[-1] if len(lines) > 0 else ""
            else:
                last_question = "请描述你对这个主题的理解。"

            # 生成反馈
            feedback = self._generate_feedback(last_question, user_answer, plan)

            # 生成下一个问题
            next_question = self._generate_next_question(plan, [last_question, user_answer], mode)

            # 更新临时文件
            temp_file.write_text(
                f"{mode}\n{datetime.now().strftime('%Y-%m-%d %H:%M')}\n{next_question}",
                encoding='utf-8'
            )

            # 返回反馈和下一个问题
            return f"""✅ {feedback}

{next_question}

💡 输入你的回答，或输入"退出"结束会话
"""

        except Exception as e:
            # 发生错误时保存会话并返回
            return f"❌ 处理回答时发生错误：{e}\n\n会话已自动保存。"

    def _save_conversation_history(self, domain: str, mode: str, conversation: List[str], error: str = None) -> None:
        """
        保存对话历史

        Args:
            domain: 领域名称
            mode: 模式
            conversation: 对话记录
            error: 错误信息（可选）
        """
        try:
            session_path = self.file_manager.BASE_DIR / domain / "sessions"
            timestamp = datetime.now().strftime("%Y-%m-%d %H-%M")

            content = f"# 学习会话 - {domain}\n"
            content += f"模式: {mode}\n"
            content += f"时间: {timestamp}\n\n"

            if conversation:
                content += "\n".join(conversation)

            if error:
                content += f"\n\n错误: {error}"

            # 保存会话
            self.file_manager.save_session(domain, content)

        except Exception:
            pass  # 静默失败，避免干扰主流程

    def _generate_first_question(self, plan: str, mode: str) -> str:
        """
        生成第一个问题

        Args:
            plan: 学习计划
            mode: 模式（free/quiz）

        Returns:
            问题文本
        """
        if mode == "quiz":
            # quiz 模式：使用 QuizGenerator
            return self.quiz_generator.generate_question(plan, difficulty="easy")
        else:
            # free 模式：生成开放性问题
            user_prompt = f"""基于以下学习计划，生成一个开放性的问题，开始对话：

{plan[:2000]}

问题应该：
1. 从基础概念开始
2. 引导用户思考和表达
3. 不要太难，建立信心

直接返回问题，不需要额外说明。
"""

            messages = [
                {
                    "role": "system",
                    "content": "你是一个专业的学习教练，擅长通过提问引导学习。",
                },
                {"role": "user", "content": user_prompt},
            ]

            try:
                if self.streaming:
                    from utils.streaming import stream_response
                    return stream_response(self.llm, messages)
                else:
                    return self.llm.invoke(messages).strip()
            except Exception:
                return "请简单描述一下你对这个主题的理解，以及你最想学习的部分是什么？"

    def _generate_next_question(
        self, plan: str, history: List[str], mode: str
    ) -> str:
        """
        生成下一个问题（根据历史对话调整）

        Args:
            plan: 学习计划
            history: 对话历史
            mode: 模式

        Returns:
            问题文本
        """
        # 提取最后一个问题和回答（如果有）
        if len(history) < 3:
            return self._generate_first_question(plan, mode)

        if mode == "quiz":
            # quiz 模式：逐步增加难度
            difficulty = min(1.0, 0.3 + len(history) * 0.1)
            return self.quiz_generator.generate_question(plan, difficulty=difficulty)
        else:
            # free 模式：基于上下文生成问题
            recent_context = "\n".join(history[-5:])

            user_prompt = f"""基于以下对话历史，生成下一个问题：

{recent_context}

要求：
1. 继续深入探讨
2. 根据用户之前的回答调整方向
3. 保持对话流畅性

直接返回问题，不需要额外说明。
"""

            messages = [
                {
                    "role": "system",
                    "content": "你是一个专业的学习教练，擅长通过对话引导深入学习。",
                },
                {"role": "user", "content": user_prompt},
            ]

            try:
                if self.streaming:
                    from utils.streaming import stream_response
                    return stream_response(self.llm, messages)
                else:
                    return self.llm.invoke(messages).strip()
            except Exception:
                return "请继续分享你的想法，或者有什么具体的问题想讨论吗？"

    def _generate_feedback(
        self, question: str, answer: str, plan: str
    ) -> str:
        """
        生成反馈

        Args:
            question: 问题
            answer: 用户回答
            plan: 学习计划

        Returns:
            反馈文本
        """
        user_prompt = f"""问题：{question}

用户回答：{answer}

参考计划：{plan[:1000]}

生成友好的反馈（100字以内）：
1. 肯定正确的部分
2. 指出需要改进的地方（温和地）
3. 提供一个额外的知识点或建议
"""

        messages = [
            {
                "role": "system",
                "content": "你是一个友善的学习教练，善于鼓励和引导。",
            },
            {"role": "user", "content": user_prompt},
        ]

        try:
            if self.streaming:
                from utils.streaming import stream_response
                return stream_response(self.llm, messages)
            else:
                return self.llm.invoke(messages).strip()
        except Exception:
            return "好的，谢谢你的回答。让我们继续深入探讨这个话题。"

    def _evaluate_answer(
        self, question: str, answer: str, plan: str
    ) -> Dict[str, any]:
        """
        评估回答质量

        Args:
            question: 问题
            answer: 回答
            plan: 学习计划

        Returns:
            评估结果（包含 score, mastery_level, suggested_next）
        """
        user_prompt = f"""评估以下回答的质量（0-1分）：

问题：{question}

回答：{answer}

返回 JSON 格式：
{{
  "score": 0.8,
  "mastery_level": "good/poor/medium",
  "suggested_next": "increase/maintain/decrease"
}}

只返回 JSON，不需要其他内容。
"""

        messages = [
            {
                "role": "system",
                "content": "你是一个教育评估专家，擅长评估学生的学习质量。",
            },
            {"role": "user", "content": user_prompt},
        ]

        try:
            response = self.llm.invoke(messages).strip()

            # 尝试解析 JSON
            # 简化实现：使用规则提取
            return self._extract_evaluation(response)

        except Exception:
            # 降级：返回默认评估
            return {
                "score": 0.5,
                "mastery_level": "medium",
                "suggested_next": "maintain",
            }

    def _extract_evaluation(self, text: str) -> Dict[str, any]:
        """
        从文本中提取评估结果（简化版）

        Args:
            text: LLM 响应文本

        Returns:
            评估结果字典
        """
        # 简化实现：返回默认值
        # 在真实场景中，应该使用更健壮的 JSON 解析
        try:
            # 尝试直接解析
            return json.loads(text)
        except:
            # 失败则返回默认值
            return {
                "score": 0.5,
                "mastery_level": "medium",
                "suggested_next": "maintain",
            }

    def _summarize_session(self, conversation: List[str], domain: str) -> str:
        """
        总结会话

        Args:
            conversation: 对话历史
            domain: 领域名称

        Returns:
            会话总结
        """
        content = "\n".join(conversation)

        user_prompt = f"""总结以下学习会话（控制在200字以内）：

{content[:3000]}

包括：
1. 讨论的主题
2. 用户掌握良好的知识点
3. 需要复习的内容
4. 下次学习的建议

输出格式：
## 会话总结

**讨论主题：** ...

**掌握情况：**
- ...

**需要复习：**
- ...

**下一步建议：**
- ...
"""

        messages = [
            {
                "role": "system",
                "content": "你是一个学习总结专家，擅长提炼关键信息。",
            },
            {"role": "user", "content": user_prompt},
        ]

        try:
            return self.llm.invoke(messages).strip()
        except Exception:
            return f"## 会话总结\n\n完成了 {domain} 领域的学习会话。\n继续加油！"
