import ConfigControl from '../config/configControl.js';
import toolRegistry from './tools/toolRegistry.js';
import OpenaiChat from '../../modules/openai/openaiChat.js';

/**
 * ReAct引擎
 * Reasoning + Acting 循环
 */
class ReactEngine {
  constructor() {
    this.maxIterations = 8;
    this.timeout = 45000;
    this.enableThinking = false;
  }

  async init() {
    try {
      const config = await ConfigControl.get('ai');
      const reactConfig = config?.reactConfig || {};
      
      this.maxIterations = reactConfig.maxIterations || 8;
      this.timeout = reactConfig.timeout || 45000;
      this.enableThinking = reactConfig.enableThinking || false;
      
      logger.info('[crystelf-ai] ReAct引擎初始化完成');
    } catch (error) {
      logger.error(`[crystelf-ai] ReAct引擎初始化失败: ${error.message}`);
    }
  }

  /**
   * 执行标准ReAct循环
   * @param {string} userInput - 用户输入
   * @param {Object} context - 执行上下文
   * @returns {Promise<Object>} 执行结果
   */
  async execute(userInput, context) {
    const startTime = Date.now();
    const responseQueue = [];
    const thinkingHistory = [];
    
    try {
      logger.info(`[crystelf-ai] 开始标准ReAct循环，用户输入: ${userInput.substring(0, 50)}...`);
      
      // 第一阶段：思考和信息收集
      const phase1Result = await this.executePhase1_ThinkingAndCollection(userInput, context, thinkingHistory);
      
      if (!phase1Result.success) {
        return {
          success: false,
          error: phase1Result.error,
          responses: [{
            type: 'message',
            data: '抱歉，我在分析您的问题时遇到了困难...',
            at: -1,
            quote: -1,
            recall: false
          }],
          thinkingHistory: this.enableThinking ? thinkingHistory : []
        };
      }

      // 第二阶段：基于收集的信息生成回复
      const phase2Result = await this.executePhase2_ResponseGeneration(
        userInput, 
        context, 
        phase1Result.collectedInfo,
        phase1Result.conversationMessages,
        responseQueue
      );

      return {
        success: true,
        responses: responseQueue,
        thinkingHistory: this.enableThinking ? thinkingHistory : [],
        collectedInfo: phase1Result.collectedInfo,
        conversationMessages: this.enableThinking ? phase1Result.conversationMessages : [],
        duration: Date.now() - startTime
      };

    } catch (error) {
      logger.error(`[crystelf-ai] ReAct执行失败: ${error.message}`);
      
      return {
        success: false,
        error: error.message,
        responses: [{
          type: 'message',
          data: '抱歉，我在处理您的请求时遇到了问题...',
          at: -1,
          quote: -1,
          recall: false
        }],
        thinkingHistory: this.enableThinking ? thinkingHistory : []
      };
    }
  }

  /**
   * 第一阶段：思考和信息收集
   * 只包含信息收集工具，不包含回复工具和人设
   */
  async executePhase1_ThinkingAndCollection(userInput, context, thinkingHistory) {
    const startTime = Date.now();
    
    // 构建第一阶段的消息历史
    const conversationMessages = await this.buildPhase1Messages(userInput, context);
    
    // 获取信息收集工具（不包含回复工具）
    const collectionTools = this.getCollectionTools();
    
    logger.info(`[crystelf-ai] 第一阶段开始 - 思考和信息收集`);
    
    let foundAnswer = false;
    let collectedInfo = '';
    
    // 🔥 物理循环：for 循环提供执行框架
    for (let iteration = 0; iteration < this.maxIterations; iteration++) {
      // 检查超时
      if (Date.now() - startTime > this.timeout) {
        logger.warn(`[crystelf-ai] 第一阶段超时，已迭代 ${iteration} 次`);
        break;
      }

      logger.info(`[crystelf-ai] 第一阶段第${iteration + 1}轮：AI思考和决策`);
      
      try {
        // 🔥 每轮都是独立的 AI 调用
        const aiResponse = await this.callAIWithTools(conversationMessages, collectionTools);
        
        // 将AI的回复添加到对话历史
        conversationMessages.push(aiResponse);
        
        // 🔥 AI 可以做出不同决策
        if (aiResponse.tool_calls && aiResponse.tool_calls.length > 0) {
          // 决策1：调用工具继续探索
          logger.info(`[crystelf-ai] AI决定调用 ${aiResponse.tool_calls.length} 个工具`);
          
          // 并行执行所有工具
          const toolResults = await this.executeToolsParallel(
            aiResponse.tool_calls, 
            conversationMessages, 
            context
          );
          
          // 记录思考步骤
          thinkingHistory.push({
            phase: 1,
            iteration: iteration + 1,
            aiThought: aiResponse.content || '进行工具调用',
            toolCalls: aiResponse.tool_calls,
            toolResults: toolResults,
            timestamp: Date.now()
          });
          
          // 检查AI是否通过工具调用标记找到答案
          const answerResult = toolResults.find(result => 
            result.toolName === 'found_answer' || result.toolName === 'not_enough_info'
          );
          
          if (answerResult) {
            if (answerResult.toolName === 'found_answer') {
              // 决策2：找到答案，标记找到答案，跳出循环到答案回复
              foundAnswer = true;
              collectedInfo = answerResult.result.answerSummary || '';
              logger.info(`[crystelf-ai] AI找到答案，跳出循环进入第二阶段`);
              break; // 🔥 跳出物理循环
            } else {
              // AI明确表示信息不足，结束收集
              logger.info(`[crystelf-ai] AI认为信息不足，结束收集阶段`);
              return {
                success: false,
                error: `信息收集失败: ${answerResult.result.reason}`,
                collectedInfo: '',
                conversationMessages
              };
            }
          }
          
        } else {
          // 决策3：继续思考，下一轮再决策
          logger.info(`[crystelf-ai] AI进行纯思考: ${aiResponse.content?.substring(0, 100)}...`);
          
          thinkingHistory.push({
            phase: 1,
            iteration: iteration + 1,
            aiThought: aiResponse.content || '继续思考',
            toolCalls: [],
            toolResults: [],
            timestamp: Date.now()
          });
          
          // continue 到下一轮循环
        }
        
      } catch (error) {
        logger.error(`[crystelf-ai] 第一阶段第${iteration + 1}轮失败: ${error.message}`);
        break;
      }
    }

    // 如果循环结束仍未找到答案，进行最终评估
    if (!foundAnswer) {
      logger.info(`[crystelf-ai] 达到最大迭代次数，进行最终评估`);
      
      const finalEvaluation = await this.performFinalEvaluation(conversationMessages, collectionTools);
      
      if (finalEvaluation.foundAnswer) {
        foundAnswer = true;
        collectedInfo = finalEvaluation.answerSummary;
      } else {
        return {
          success: false,
          error: `经过${this.maxIterations}轮思考仍未找到足够信息`,
          collectedInfo: '',
          conversationMessages
        };
      }
    }

    return {
      success: foundAnswer,
      collectedInfo,
      conversationMessages,
      iterations: this.maxIterations
    };
  }

  /**
   * 第二阶段：基于收集的信息生成回复
   * 包含人设和回复工具，基于第一阶段的思考结果
   */
  async executePhase2_ResponseGeneration(userInput, context, collectedInfo, phase1Messages, responseQueue) {
    logger.info(`[crystelf-ai] 第二阶段开始 - 基于收集信息生成回复`);
    
    // 构建第二阶段的消息历史（包含人设和第一阶段结果）
    const phase2Messages = await this.buildPhase2Messages(userInput, context, collectedInfo, phase1Messages);
    
    // 获取回复工具（包含所有回复相关工具）
    const responseTools = this.getResponseTools();
    
    try {
      // AI基于收集的信息生成回复
      const aiResponse = await this.callAIWithTools(phase2Messages, responseTools);
      
      if (aiResponse.tool_calls && aiResponse.tool_calls.length > 0) {
        // AI调用回复工具
        logger.info(`[crystelf-ai] AI调用 ${aiResponse.tool_calls.length} 个回复工具`);
        
        await this.executeResponseTools(aiResponse.tool_calls, responseQueue, context);
        
      } else if (aiResponse.content) {
        // AI直接给出文本回复
        responseQueue.push({
          type: 'message',
          data: aiResponse.content,
          at: -1,
          quote: -1,
          recall: false
        });
      }
      
      return { success: true };
      
    } catch (error) {
      logger.error(`[crystelf-ai] 第二阶段失败: ${error.message}`);
      
      // 添加默认回复
      responseQueue.push({
        type: 'message',
        data: '我已经收集了相关信息，但在生成回复时遇到了问题...',
        at: -1,
        quote: -1,
        recall: false
      });
      
      return { success: false, error: error.message };
    }
  }

  /**
   * 构建第一阶段消息（思考阶段，不包含人设）
   */
  async buildPhase1Messages(userInput, context) {
    const systemPrompt = `你是一个信息分析专家，需要分析用户的问题并收集相关信息。

=== 分析任务 ===
用户问题："${userInput}"

请分析：
1. 用户想要什么信息？
2. 需要搜索哪些相关内容？
3. 应该使用什么工具来收集信息？

=== 可用工具 ===
- search_memory: 搜索用户的历史记忆和偏好
- get_chat_history: 获取最近的聊天记录
- found_answer: 当收集到足够信息时标记找到答案
- not_enough_info: 当认为信息不足时标记

=== 重要规则 ===
1. 可以同时调用多个工具来并行收集信息
2. 仔细分析每个工具的结果
3. 当有足够信息回答用户问题时，调用found_answer
4. 如果多次尝试仍无法找到足够信息，调用not_enough_info
5. 专注于信息收集，不要尝试直接回答用户

请开始分析用户问题并收集相关信息。`;

    return [
      { role: 'system', content: systemPrompt },
      { role: 'user', content: `请分析这个问题并收集相关信息："${userInput}"` }
    ];
  }

  /**
   * 构建第二阶段消息（回复阶段，包含人设和第一阶段结果）
   */
  async buildPhase2Messages(userInput, context, collectedInfo, phase1Messages) {
    const { e } = context;
    const config = await ConfigControl.get();
    
    const botInfo = {
      id: e.bot?.uin || '未知',
      name: config?.profile?.nickName || '晶灵',
    };

    const userInfo = {
      id: e.user_id || e.sender?.user_id || '未知',
      name: e.sender?.card || e.sender?.nickname || '用户',
      isMaster: e.isMaster,
    };

    const now = Date.now();
    const date = new Date(now);
    const formatDate = date.toLocaleDateString('zh-CN');
    const formatTime = date.toLocaleTimeString('zh-CN');

    // 提取第一阶段的思考过程摘要
    const thinkingProcess = this.extractThinkingProcess(phase1Messages);

    const systemPrompt = `你是一个名为${botInfo.name}的智能助手，具有以下特征：
1. 性格温和友善，喜欢帮助用户解决问题
2. 知识渊博，能够回答各种问题
3. 偶尔会使用一些可爱的表情和语气
4. 会记住与用户的对话内容，提供个性化的回复
5. 能够理解中文语境和网络用语
6. 回复简洁明了，避免过于冗长

=== 当前对话信息 ===
- 你的昵称：${botInfo.name}
- 你的QQ号：${botInfo.id}
- 用户昵称：${userInfo.name}
- 用户QQ号：${userInfo.id}
- 用户是否为主人：${userInfo.isMaster ? '是' : '否'}
- 当前时间：${formatDate} ${formatTime}

=== 用户问题 ===
"${userInput}"

=== 已收集的信息 ===
${collectedInfo}

=== 思考过程摘要 ===
${thinkingProcess}

=== 回复指南 ===
基于以上收集的信息，请给用户一个准确、友好的回复。你可以使用以下工具：
- send_message: 发送文本消息（支持@用户和引用消息）
- send_meme: 发送表情包
- render_code: 渲染代码为图片
- render_markdown: 渲染Markdown为图片
- generate_image: 生成图片
- store_memory: 存储重要信息
- poke_user: 戳一戳用户

请根据收集的信息给出最合适的回复。`;

    return [
      { role: 'system', content: systemPrompt },
      { role: 'user', content: `请基于收集的信息回复用户的问题："${userInput}"` }
    ];
  }

  /**
   * 获取信息收集工具（第一阶段使用）
   */
  getCollectionTools() {
    const allTools = toolRegistry.getToolSchemas();
    const collectionToolNames = [
      'search_memory',
      'get_chat_history', 
      'found_answer',
      'not_enough_info'
    ];
    
    return allTools.filter(tool => 
      collectionToolNames.includes(tool.function.name)
    );
  }

  /**
   * 获取回复工具（第二阶段使用）
   */
  getResponseTools() {
    const allTools = toolRegistry.getToolSchemas();
    const responseToolNames = [
      'send_message',
      'send_meme',
      'render_code',
      'render_markdown', 
      'generate_image',
      'store_memory',
      'poke_user'
    ];
    
    return allTools.filter(tool => 
      responseToolNames.includes(tool.function.name)
    );
  }

  /**
   * 并行执行工具
   */
  async executeToolsParallel(toolCalls, conversationMessages, context) {
    const toolPromises = toolCalls.map(async (toolCall) => {
      const toolName = toolCall.function.name;
      const parameters = JSON.parse(toolCall.function.arguments);
      
      logger.info(`[crystelf-ai] 执行工具: ${toolName}(${JSON.stringify(parameters)})`);
      
      try {
        const result = await toolRegistry.executeTool(toolName, parameters, context);
        
        // 将工具结果添加到对话历史
        conversationMessages.push({
          role: 'tool',
          tool_call_id: toolCall.id,
          content: JSON.stringify({
            success: result.success,
            message: result.message || result.result,
            data: result
          })
        });
        
        return {
          toolName,
          parameters,
          result,
          success: result.success !== false,
          toolCallId: toolCall.id
        };
        
      } catch (error) {
        logger.error(`[crystelf-ai] 工具执行失败: ${toolName} - ${error.message}`);
        
        conversationMessages.push({
          role: 'tool',
          tool_call_id: toolCall.id,
          content: JSON.stringify({
            success: false,
            error: error.message
          })
        });
        
        return {
          toolName,
          parameters,
          result: { success: false, message: error.message },
          success: false,
          toolCallId: toolCall.id,
          error: error.message
        };
      }
    });
    
    return await Promise.all(toolPromises);
  }

  /**
   * 执行回复工具
   */
  async executeResponseTools(toolCalls, responseQueue, context) {
    for (const toolCall of toolCalls) {
      const toolName = toolCall.function.name;
      const parameters = JSON.parse(toolCall.function.arguments);
      
      try {
        const result = await toolRegistry.executeTool(toolName, parameters, {
          ...context,
          responseQueue
        });
        
        logger.info(`[crystelf-ai] 回复工具执行成功: ${toolName}`);
        
      } catch (error) {
        logger.error(`[crystelf-ai] 回复工具执行失败: ${toolName} - ${error.message}`);
      }
    }
  }

  /**
   * 最终评估（当达到最大迭代次数时）
   */
  async performFinalEvaluation(conversationMessages, collectionTools) {
    logger.info(`[crystelf-ai] 执行最终评估`);
    
    // 添加最终评估提示
    conversationMessages.push({
      role: 'user',
      content: '已达到最大搜索次数，请基于目前收集的所有信息做最终判断：是否有足够信息回答用户问题？请调用found_answer或not_enough_info工具。'
    });
    
    try {
      const aiResponse = await this.callAIWithTools(conversationMessages, collectionTools);
      
      if (aiResponse.tool_calls && aiResponse.tool_calls.length > 0) {
        const finalTool = aiResponse.tool_calls[0];
        const toolName = finalTool.function.name;
        const parameters = JSON.parse(finalTool.function.arguments);
        
        if (toolName === 'found_answer') {
          return {
            foundAnswer: true,
            answerSummary: parameters.answer_summary || '基于收集的信息可以回答'
          };
        }
      }
      
      return { foundAnswer: false };
      
    } catch (error) {
      logger.error(`[crystelf-ai] 最终评估失败: ${error.message}`);
      return { foundAnswer: false };
    }
  }

  /**
   * 提取思考过程摘要
   */
  extractThinkingProcess(phase1Messages) {
    const thinkingSteps = [];
    
    for (let i = 0; i < phase1Messages.length; i++) {
      const message = phase1Messages[i];
      
      if (message.role === 'assistant' && message.tool_calls) {
        const toolNames = message.tool_calls.map(tc => tc.function.name).join(', ');
        thinkingSteps.push(`调用了工具: ${toolNames}`);
      } else if (message.role === 'tool') {
        try {
          const toolResult = JSON.parse(message.content);
          if (toolResult.success) {
            thinkingSteps.push(`获得结果: ${toolResult.message}`);
          }
        } catch (e) {
          // 忽略解析错误
        }
      }
    }
    
    return thinkingSteps.length > 0 ? thinkingSteps.join('\n') : '进行了信息收集和分析';
  }

  /**
   * 调用AI（工具调用模式）
   */
  async callAIWithTools(messages, tools) {
    const config = await ConfigControl.get('ai');
    const apiCaller = new OpenaiChat();
    apiCaller.init(config.apiKey, config.baseApi);
    
    try {
      const completion = await apiCaller.openai.chat.completions.create({
        model: config.modelType,
        messages: messages,
        tools: tools,
        tool_choice: 'auto',
        temperature: config.temperature || 0.7,
        parallel_tool_calls: true
      });

      const message = completion.choices[0].message;
      
      if (message.tool_calls && message.tool_calls.length > 0) {
        logger.info(`[crystelf-ai] AI调用工具: ${message.tool_calls.map(tc => tc.function.name).join(', ')}`);
      } else {
        logger.info(`[crystelf-ai] AI文本回复: ${message.content?.substring(0, 50)}...`);
      }
      
      return message;
      
    } catch (error) {
      logger.error(`[crystelf-ai] AI调用失败: ${error.message}`);
      throw error;
    }
  }
}

export default new ReactEngine();