import MemorySystem from "./memorySystem.js";
import configControl from "../config/configControl.js";

/**
 * 响应处理器
 * 处理AI返回的规范化响应
 */
class ResponseHandler {
  constructor() {
    this.memorySystem = MemorySystem;
  }

  /**
   * 处理ai响应
   * @param rawResponse ai原始回复
   * @param userMessage 用户消息
   * @param groupId 群聊id
   * @param user_id 用户id
   * @returns {Promise<[{type: string, data: string, at: boolean, quote: boolean, recall: number}]|Array|*[]>}
   */
  async processResponse(rawResponse, userMessage, groupId,user_id) {
    try {
      // 检查是否是ReAct模式的响应
      if (Array.isArray(rawResponse)) {
        logger.info('[crystelf-ai] 处理ReAct模式响应');
        return await this.processReActResponse(rawResponse, userMessage, groupId, user_id);
      }

      // 传统模式响应处理
      const parsedResponse = this.parseAiResponse(rawResponse);
      if (!parsedResponse.success) {
        logger.error(`[crystelf-ai] 解析AI响应失败: ${parsedResponse.error}`);
        return this.createErrorResponse(parsedResponse.error);
      }
      const messages = parsedResponse.messages;
      const processedMessages = [];
      for (const message of messages) {
        const processedMessage = await this.processMessage(message, userMessage, groupId,user_id);
        if (processedMessage) {
          processedMessages.push(processedMessage);
        }
      }
      if (processedMessages.length === 0) {
        return this.createDefaultResponse();
      }
      return processedMessages;
    } catch (error) {
      logger.error(`[crystelf-ai] 处理响应失败: ${error.message}`);
      return this.createErrorResponse('处理响应时发生错误');
    }
  }

  /**
   * 处理ReAct模式响应
   * @param responses ReAct响应数组
   * @param userMessage 用户消息
   * @param groupId 群聊id
   * @param user_id 用户id
   * @returns {Promise<Array>} 处理后的消息数组
   */
  async processReActResponse(responses, userMessage, groupId, user_id) {
    const processedMessages = [];
    
    for (const response of responses) {
      const processedMessage = await this.processMessage(response, userMessage, groupId, user_id);
      if (processedMessage) {
        processedMessages.push(processedMessage);
      }
    }

    if (processedMessages.length === 0) {
      return this.createDefaultResponse();
    }

    return processedMessages;
  }

  parseAiResponse(response) {
    try {
      const cleanResponse = this.cleanResponseText(response);
      const parsed = JSON.parse(cleanResponse);
      if (Array.isArray(parsed)) {
        return {
          success: true,
          messages: parsed
        };
      } else {
        return {
          success: true,
          messages: [parsed]//处理模型降智返回对象的情况
        };
      }
    } catch (error) {
      logger.warn(`[crystelf-ai] AI返回非JSON格式: ${error.message}`);
    }
  }

  /**
   * 清理响应文本
   * @param {string} text 原始文本
   * @returns {string} 清理后的文本
   */
  cleanResponseText(text) {
    if (!text) return '';
    let cleaned = text.replace(/```json\s*/g, '').replace(/```\s*/g, '');
    cleaned = cleaned.trim();
    return cleaned;
  }

  async processMessage(message, userMessage, groupId,userId) {
    try {
      if (!this.validateMessage(message)) {
        logger.warn(`[crystelf-ai] 无效消息格式: ${JSON.stringify(message)}`);
        return null;
      }
      switch (message.type) {
        case 'memory':
          await this.handleMemoryMessage(message, groupId,userId);
          return null;
        case 'image':
          return this.handleImageMessage(message);
        default:
          return this.handleNormalMessage(message);
      }
    } catch (error) {
      logger.error(`[crystelf-ai] 处理消息失败: ${error.message}`);
      return null;
    }
  }

  validateMessage(message) {
    if (!message || typeof message !== 'object') {
      logger.info('[crystelf-ai] ai返回为空或不是对象')
      return false;
    }
    if (!message.type) {
      logger.info('[crystelf-ai] ai响应未包含type值')
      return false;
    }
    const validTypes = [
      'message', 'code', 'markdown', 'meme', 'at', 'poke','memory','image'
    ];
    if (!validTypes.includes(message.type)) {
      logger.info(`[crystelf-ai] ai返回未知的type类型:${message.type}`)
      return false;
    }return true;
  }

  /**
   * 记忆消息
   * @param message 记忆
   * @param groupId 群聊id
   * @param user_id 用户id
   * @returns {Promise<void>}
   */
  async handleMemoryMessage(message, groupId,user_id) {
    try {
      const memoryId = await this.memorySystem.addMemory(
        groupId,
        user_id,
        message.data,
        message.key || [],
        message.timeout || 30
      );
      if (memoryId) {
        logger.info(`[crystelf-ai] 存储记忆成功: ${memoryId}`);
      }
    } catch (error) {
      logger.error(`[crystelf-ai] 存储记忆失败: ${error.message}`);
    }
  }

  //普通消息
  handleNormalMessage(message) {
    // 设置默认值
    let processedMessage = {
      type: message.type,
      data: message.data,
      at: message.at || -1,
      quote: message.quote || -1,
      recall: message.recall || false
    };
    if (message.id) processedMessage.id = message.id;
    if (message.seq) processedMessage.seq = message.seq;
    if (message.num) processedMessage.num = message.num;
    if (message.language) processedMessage.language = message.language;
    return processedMessage;
  }

  /**
   * 处理图像消息
   * @param message 图像消息
   * @returns {Object} 处理后的消息对象
   */
  handleImageMessage(message) {
    if (!message.data) {
      logger.warn('[crystelf-ai] 图像消息缺少data字段');
      return null;
    }
    
    let processedMessage = {
      type: 'image',
      data: message.data,
      at: message.at || -1,
      quote: message.quote || -1,
      recall: message.recall || false
    };
    
    if (message.style) processedMessage.style = message.style;
    if (message.quality) processedMessage.quality = message.quality;
    if (message.size) processedMessage.size = message.size;
    
    return processedMessage;
  }

  createErrorResponse(error) {
    const nickName = configControl.get('profile')?.nickName;
    return [{
      type: 'message',
      data: `${nickName}的服务器去火星开小差了..`,
      at: -1,
      quote: -1,
      recall: true
    }];
  }

  createDefaultResponse() {
    const nickName = configControl.get('profile')?.nickName;
    return [{
      type: 'message',
      data: `${nickName}的服务器去火星开小差了..`,
      at: -1,
      quote: -1,
      recall: true
    }];
  }
}

export default new ResponseHandler();
