/**
 * Agent 类
 * 负责对话和推理
 */

const { EventEmitter } = require('../utils/event-emitter');
const { AgentChatHandler } = require('./agent-chat');
const { SystemPromptBuilder } = require('./system-prompt-builder');
const { zodSchemaToMarkdown, zodSchemaToTable } = require('@chnak/zod-to-markdown');
const { zodSchema } = require('ai');
const os = require('os');

/**
 * System Prompt 优先级常量
 * 统一管理所有 prompt 部分的优先级，避免魔法数字
 */
const PROMPT_PRIORITY = {
  ORIGINAL_PROMPT: 100,
  SHARED_PROMPT: 200,
  METADATA: 300,
  TOOLS: 400,
  SKILLS: 500,
  SUB_AGENTS: 600,
  CAPABILITIES: 700,
  MCP_TOOLS: 750,
  EXTENSION_TOOLS: 800,
  TOOL_CORE_RULES: 1000,
};

/**
 * Agent 配置常量
 * 统一管理配置参数，避免魔法数字
 */
const AGENT_CONFIG = {
  // AI 模型配置
  MAX_OUTPUT_TOKENS: 8192,
  TEMPERATURE: 0.3,
  // 通知数量限制
  MAX_NOTIFICATIONS: 5,
  // 元数据提取配置
  CAPABILITY_MAX_LENGTH: 50,
  CAPABILITY_MAX_PARTS: 3,
  // 错误重试配置
  MAX_RETRIES: 3,
};

/**
 * 日志工具函数
 * @param {string} level - 日志级别
 * @param {string} context - 上下文信息
 * @param {string} message - 日志消息
 * @param {any} data - 附加数据
 */
function log(level, context, message, data = null) {
  const timestamp = new Date().toISOString();
  const prefix = `[${timestamp}] [${level}] [${context}]`;
  if (data !== null) {
    console.log(`${prefix} ${message}`, data);
  } else {
    console.log(`${prefix} ${message}`);
  }
}

const logger = {
  info: (context, message, data) => log('INFO', context, message, data),
  warn: (context, message, data) => log('WARN', context, message, data),
  error: (context, message, data) => log('ERROR', context, message, data),
  debug: (context, message, data) => log('DEBUG', context, message, data),
};

class Agent extends EventEmitter {
  /**
   * @param {Framework} framework - 框架实例
   * @param {Object} config - 配置
   * @param {string} [config.name] - Agent 名称
   * @param {string} [config.systemPrompt] - 系统提示
   * @param {string} [config.sharedPrompt] - 共享提示模板，支持 {{VAR}} 占位符
   * @param {Object} [config.metadata] - 元数据，注入到 sharedPrompt
   * @param {boolean} [config.enableToolRouting=true] - 是否启用工具路由
   */
  constructor(framework, config = {}) {
    super();

    this.framework = framework;
    this.config = config;

    this.name = config.name || 'Agent';
    this.model = config.model || 'deepseek-chat';
    this.apiKey = config.apiKey;
    this.baseURL = config.baseURL;
    this.provider = config.provider || 'deepseek';
    this.providerOptions = config.providerOptions || {};
    // 使用常量替代硬编码数字
    this.providerOptions.maxOutputTokens = AGENT_CONFIG.MAX_OUTPUT_TOKENS;
    this.providerOptions.temperature = AGENT_CONFIG.TEMPERATURE;
    // 原始 system prompt
    this._originalPrompt =
      config.systemPrompt ||
      '你是一个智能助手。当用户提出问题或任务时，你会主动分析需求，选择合适的工具来获取信息或执行操作。你善于将复杂任务拆解为多个步骤，通过工具协作完成。';

    // 共享提示模板
    this._sharedPrompt = config.sharedPrompt || '';

    // 元数据
    const metadata = config.metadata || {};
    this._metadata = new Map(Object.entries(metadata));

    this._chatHandler = null;
    this._tools = new Map();
    this._status = 'idle';

    // 子Agent管理
    this._subAgents = new Map();

    // System prompt 构建器
    this._systemPromptBuilder = new SystemPromptBuilder();
    this._registerDefaultPromptParts();

    // 处理后的 system prompt (带上下文)
    this.systemPrompt = this._buildSystemPrompt();

    // 初始化聊天处理器
    this._initChatHandler();

    // logger.info('Agent', `Agent "${this.name}" 初始化完成`);
  }

  /**
   * 注册默认的系统提示词部分
   * @private
   */
  _registerDefaultPromptParts() {
    // 1. 原始 system prompt
    this._systemPromptBuilder.register(
      'original-prompt',
      PROMPT_PRIORITY.ORIGINAL_PROMPT,
      () => this._originalPrompt
    );

    // 2. 共享提示模板
    this._systemPromptBuilder.register('shared-prompt', PROMPT_PRIORITY.SHARED_PROMPT, () => {
      if (this._sharedPrompt) {
        return this._replacePlaceholders(this._sharedPrompt);
      }
      return null;
    });

    // 3. 日期时间（每次构建时都重新获取）
    this._systemPromptBuilder.register('datetime', 50, () => {
      const now = new Date();
      const timeStr = now.toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' });
      const dateStr = now.toLocaleDateString('zh-CN', {
        timeZone: 'Asia/Shanghai',
        weekday: 'long',
      });
      return `【当前时间】${timeStr}（${dateStr}）`;
    });

    // 4. 元数据
    this._systemPromptBuilder.register('metadata', PROMPT_PRIORITY.METADATA, () => {
      if (this._metadata.size === 0) {
        return null;
      }
      const metaParts = ['【元数据】'];
      for (const [key, value] of this._metadata) {
        if (typeof value === 'object') {
          metaParts.push(`- ${key}: ${JSON.stringify(value)}`);
        } else {
          metaParts.push(`- ${key}: ${value}`);
        }
      }
      return metaParts.join('\n');
    });

    // 4. 工具列表 (优先级 400)
    //this._systemPromptBuilder.register('tools', PROMPT_PRIORITY.TOOLS, () => this._buildToolsDescription());

    // 5. 技能列表
    this._systemPromptBuilder.register('skills', PROMPT_PRIORITY.SKILLS, () =>
      this._buildSkillsDescription()
    );

    // 6. 子Agent列表
    this._systemPromptBuilder.register('subagents', PROMPT_PRIORITY.SUB_AGENTS, () =>
      this._buildSubAgentsDescription()
    );

    // 7. 系统能力
    this._systemPromptBuilder.register('capabilities', PROMPT_PRIORITY.CAPABILITIES, () =>
      this._buildCapabilitiesDescription()
    );
    // 8. MCP 工具列表
    // this._systemPromptBuilder.register('mcp-tools', PROMPT_PRIORITY.MCP_TOOLS, () =>
    //   this._buildMcpToolsDescription()
    // );
    // 9. 扩展工具列表
    this._systemPromptBuilder.register('extension-tools', PROMPT_PRIORITY.EXTENSION_TOOLS, () =>
      this._buildExtensionToolsDescription()
    );
    // 10. 工具调用核心规则
    this._systemPromptBuilder.register('tool-core-rules', PROMPT_PRIORITY.TOOL_CORE_RULES, () =>
      this._getToolCoreRules()
    );
  }

  /**
   * 获取元数据值
   */
  _getMetadataValue(key) {
    // 优先从 metadata 获取
    if (this._metadata.has(key)) {
      return this._metadata.get(key);
    }

    // 内置变量
    switch (key) {
      case 'WORK_DIR':
      case 'CWD':
        return process.cwd();
      case 'HOME_DIR':
        return os.homedir();
      case 'HOST_NAME':
        return os.hostname();
      case 'PLATFORM':
        return process.platform;
      case 'TIME':
        return new Date().toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' });
      case 'DATE':
        return new Date().toISOString().split('T')[0];
      default:
        return `{{${key}}}`;
    }
  }

  /**
   * 替换 sharedPrompt 中的占位符
   */
  _replacePlaceholders(template) {
    return template.replace(/\{\{(\w+)\}\}/g, (match, key) => {
      return this._getMetadataValue(key);
    });
  }

  /**
   * 构建工具描述（直接调用的工具）
   */
  _buildToolsDescription() {
    if (this._tools.size === 0) {
      return '';
    }

    const directTools = [];

    for (const [name, tool] of this._tools) {
      if (!tool.description) continue;

      // MCP 和 ext 工具不在这里显示，它们通过专门的描述部分提供
      if (name.startsWith('mcp_') || name.startsWith('ext_') || name.startsWith('workflow_')) {
        continue;
      }

      directTools.push({ name, tool });
    }

    if (directTools.length === 0) {
      return '';
    }

    // 使用数组收集 + join 优化字符串拼接
    const lines = ['## 可用工具', ''];
    for (const { name, tool } of directTools) {
      lines.push(`- **${name}**: ${tool.description || '无描述'}`);
    }

    return lines.join('\n');
  }

  /**
   * 构建技能描述
   */
  _buildSkillsDescription() {
    const skillManager = this.framework.pluginManager.get('skill-manager');
    if (!skillManager) {
      return '';
    }

    const skills = skillManager.getAllSkills();
    if (!skills || skills.length === 0) {
      return '';
    }

    // 使用数组收集 + join 优化字符串拼接
    const lines = ['## 可用技能', ''];
    for (const skill of skills) {
      const name = skill.metadata?.name || skill.name || 'unknown';
      const descText = skill.metadata?.description || '';
      lines.push(`- ${name}: ${descText}`);
    }
    lines.push(
      '',
      '> **重要提示**：当需要开发插件、执行专业任务时，必须先使用 `loadSkill` 工具加载对应技能，获取专业指导。'
    );

    return lines.join('\n');
  }

  /**
   * 构建系统能力描述
   */
  _buildCapabilitiesDescription() {
    const plugins = this.framework.pluginManager.getAll();
    if (!plugins || plugins.length === 0) {
      return '';
    }

    // 过滤出有描述的关键插件（排除内部插件）
    const keyPlugins = plugins.filter((p) => {
      const name = p.name;
      // 排除默认配置插件和内部插件
      return name !== 'defaults' && name !== 'agent';
    });

    if (keyPlugins.length === 0) {
      return '';
    }

    // 使用数组收集 + join 优化字符串拼接
    const lines = ['## 系统能力', ''];
    keyPlugins.forEach((plugin, index) => {
      const name = plugin.instance?.name || plugin.name || 'unknown';
      const description = plugin.instance?.description || '无描述';
      lines.push(`${index + 1}. **${name}**：${description}`);
    });

    return lines.join('\n');
  }

  /**
   * 构建扩展工具描述
   * 使用 zodSchemaToMarkdown 解析参数，让 LLM 更易理解工具用法
   */
  _buildExtensionToolsDescription() {
    const extensionExecutor = this.framework.pluginManager.get('extension-executor');
    if (!extensionExecutor) {
      return '';
    }

    const extensions = extensionExecutor.getExtensions();
    if (!extensions || extensions.length === 0) {
      return '';
    }
    const mcp = this.framework.pluginManager.get('mcp');

    const sections = [
      '## Extensions 扩展工具',
      '',
      '你可以通过 `ext_call` 工具调用以下扩展插件的功能。',
      '',
      '### 调用规则',
      '',
      '> **重要**：',
      '> 1. 调用前必须指定 `plugin`（插件名）和 `tool`（工具名）',
      '> 2. 参数通过 `args` 对象传入，参数名和类型见各工具说明',
      '> 3. 必填参数（Required）必须提供，可选参数（Optional）可省略',
      '',
      '---',
      '',
    ];

    for (const ext of extensions) {
      sections.push(`### ${ext.name}`, '');
      sections.push(ext.description || '无描述', '');
      sections.push(`**版本：** ${ext.version || '1.0.0'}`, '');

      for (const tool of ext.tools) {
        sections.push(`#### \`${tool.name}\``, '');
        sections.push(tool.description || '无描述', '');
        // 使用 zodSchemaToMarkdown 解析参数
        if (ext.name === 'mcp' && mcp) {
          const mcp_desc = mcp._bindMcpParamsDesc(tool.inputSchema);
          sections.push(mcp_desc, '');
        } else if (tool.inputSchema) {
          try {
            const schemaMarkdown = zodSchemaToMarkdown(tool.inputSchema);
            sections.push('**参数：**', ' ');
            sections.push(schemaMarkdown || '无', ' ');
          } catch (e) {
            // 降级处理：尝试 zodSchemaToTable
            try {
              const schemaTable = zodSchemaToTable(tool.inputSchema);
              sections.push('**参数：**', ' ');
              sections.push(schemaTable || '无', ' ');
            } catch (e2) {
              // 最后降级：尝试简单解析
              try {
                const simpleParams = this._simpleParamsDesc(tool.inputSchema);
                sections.push('**参数：**', ' ');
                sections.push(simpleParams, ' ');
              } catch (e3) {
                sections.push('**参数：** 无可用描述', ' ');
              }
            }
          }
        }

        sections.push('');
      }
    }

    sections.push(
      '---',
      '',
      '## 调用示例',
      '',
      '### 格式',
      '```javascript',
      'ext_call({ plugin: "插件名", tool: "工具名", args: {参数} })',
      '```',
      '',
      '### 示例 - 获取余额',
      '```javascript',
      'ext_call({ plugin: "gate-trading", tool: "gate_get_account_balance", args: {} })',
      '```',
      '',
      '### 示例 - HTTP 请求',
      '```javascript',
      'ext_call({ plugin: "web", tool: "web_request", args: { method: "GET", path: "/api/data" } })',
      '```'
    );

    return sections.join('\n').trim();
  }

  /**
   * 降级处理：当 zodSchemaToMarkdown 解析失败时的备用方案
   * 支持复杂 Zod 类型如 ZodOptional、ZodUnion、ZodArray 等
   * @param {Object} schema - Zod schema 对象
   * @returns {string} 参数描述文本
   */
  _fallbackSchemaToText(schema) {
    if (!schema) {
      return '- （参数描述不可用）';
    }

    // 尝试获取 shape（标准 Zod schema）
    const shape = typeof schema.shape === 'function' ? schema.shape() : schema.shape;
    if (!shape || typeof shape !== 'object') {
      // schema 没有标准 shape，可能是 MCP 的简化 schema
      // 尝试从 properties 构建描述
      if (schema.properties) {
        const lines = [];
        for (const [name, field] of Object.entries(schema.properties)) {
          const type = field.type || 'any';
          const desc = field.description || '';
          const required = schema.required?.includes(name);
          const isOptional = required ? '' : '（可选）';
          lines.push(`- ${name} (${type}) ${isOptional}${desc ? `: ${desc}` : ''}`);
        }
        return lines.join('\n') || '- （参数描述不可用）';
      }
      return '- （参数描述不可用）';
    }

    const lines = [];
    for (const [name, field] of Object.entries(shape)) {
      const typeInfo = this._extractFieldType(field);
      const desc = typeInfo.description || '';
      const isOptional = typeInfo.isOptional ? '（可选）' : '（必填）';
      lines.push(`- ${name} (${typeInfo.type}) ${isOptional}${desc ? `: ${desc}` : ''}`);
    }

    return lines.join('\n') || '- （参数描述不可用）';
  }

  /**
   * 简单的参数描述（当 zodSchemaToMarkdown 和 zodSchemaToTable 都失败时）
   * 直接从 schema 的 properties 提取信息
   */
  _simpleParamsDesc(schema) {
    if (!schema) return '无';

    // 尝试 properties 格式
    if (schema.properties) {
      const lines = [];
      const required = schema.required || [];
      for (const [name, prop] of Object.entries(schema.properties)) {
        const type = prop.type || 'any';
        const desc = prop.description || '';
        const isRequired = required.includes(name);
        lines.push(`- ${name} (${type})${isRequired ? '' : '（可选）'}${desc ? `: ${desc}` : ''}`);
      }
      return lines.join('\n') || '无';
    }

    // 尝试直接从 schema 提取
    if (schema.jsonSchema?.properties) {
      const props = schema.jsonSchema.properties;
      const required = schema.jsonSchema.required || [];
      const lines = [];
      for (const [name, prop] of Object.entries(props)) {
        const type = prop.type || 'any';
        const desc = prop.description || '';
        const isRequired = required.includes(name);
        lines.push(`- ${name} (${type})${isRequired ? '' : '（可选）'}${desc ? `: ${desc}` : ''}`);
      }
      return lines.join('\n') || '无';
    }

    return '无';
  }

  /**
   * 递归提取字段类型信息
   * 处理 ZodOptional、ZodUnion、ZodArray 等复杂类型
   * @param {Object} field - Zod schema 字段
   * @returns {{ type: string, isOptional: boolean, description: string }}
   */
  _extractFieldType(field) {
    if (!field) {
      return { type: 'unknown', isOptional: false, description: '' };
    }

    const typeName = field._def?.typeName || field.constructor?.name || '';
    let description = field.description || field._def?.description || '';

    switch (typeName) {
      case 'ZodOptional': {
        const inner = field._def?.innerType;
        if (!inner) return { type: 'optional', isOptional: true, description };
        const innerInfo = this._extractFieldType(inner);
        return {
          type: innerInfo.type,
          isOptional: true,
          description: description || innerInfo.description,
        };
      }
      case 'ZodUnion': {
        if (!field._def?.options) return { type: 'union', isOptional: false, description };
        const types = field._def.options.map((opt) => this._extractFieldType(opt).type);
        return { type: `union(${types.join(' | ')})`, isOptional: false, description };
      }
      case 'ZodArray': {
        if (!field._def?.type) return { type: 'array', isOptional: false, description };
        const innerInfo = this._extractFieldType(field._def.type);
        return { type: `${innerInfo.type}[]`, isOptional: false, description };
      }
      case 'ZodObject': {
        if (!field._def?.shape) return { type: 'object', isOptional: false, description };
        const props = Object.keys(field._def.shape()).join(', ');
        return { type: `object{${props}}`, isOptional: false, description };
      }
      case 'ZodString':
        return { type: 'string', isOptional: false, description };
      case 'ZodNumber':
        return { type: 'number', isOptional: false, description };
      case 'ZodBoolean':
        return { type: 'boolean', isOptional: false, description };
      case 'ZodEnum': {
        const values = field._def?.values;
        if (!values) return { type: 'enum', isOptional: false, description };
        return {
          type: values.map((v) => `"${v}"`).join(' | '),
          isOptional: false,
          description,
        };
      }
      case 'ZodRecord': {
        const keyType = this._extractFieldType(field._def?.keyType);
        const valueType = this._extractFieldType(field._def?.valueType);
        return {
          type: `record<${keyType?.type || 'any'}, ${valueType?.type || 'any'}>`,
          isOptional: false,
          description,
        };
      }
      case 'ZodIntersection':
        return { type: 'intersection', isOptional: false, description };
      case 'ZodLiteral':
        return { type: JSON.stringify(field._def?.value), isOptional: false, description };
      default:
        return {
          type: typeName.replace('Zod', '').toLowerCase() || 'any',
          isOptional: false,
          description,
        };
    }
  }

  _buildMcpToolsDescription() {
    const mcpExecutor = this.framework.pluginManager.get('mcp');
    if (!mcpExecutor) {
      return '';
    }
    return mcpExecutor._buildMCPServersDescription();
  }

  /**
   * 构建子Agent描述
   * 使用数组收集 + join 模式优化字符串拼接
   * 动态从配置文件读取每个子Agent的专业领域
   */
  _buildSubAgentsDescription() {
    const subAgentManager = this.framework.pluginManager.get('subagent-manager');
    if (!subAgentManager) {
      return '';
    }
    const allSubAgents = subAgentManager.getAllSubAgents();
    if (!allSubAgents || allSubAgents.length === 0) {
      return '';
    }

    // 使用数组收集 + join 模式优化字符串拼接
    const lines = ['## 子 Agent 匹配表', ''];
    lines.push('');
    lines.push('> **提示**：根据任务类型选择最匹配的子 Agent 处理');
    lines.push('');

    // 动态从配置文件读取每个子Agent的核心能力
    for (const plugin of allSubAgents) {
      const name = plugin.name;
      const role = plugin.role;
      const goal = plugin.description || '';

      // 优先使用 SubAgentConfigManager 获取详细信息
      const config = this.framework._subAgentConfigManager?.get(name);
      if (config) {
        const agentDesc = config.getDescription();
        const skills = config.getSkills();
        let info = agentDesc || role || goal || '子代理';
        if (skills && skills.length > 0) {
          info += ` (技能: ${skills.join(', ')})`;
        }
        lines.push(`- **${name}**：${info}`);
      } else {
        // 回退到旧逻辑
        lines.push(`- **${name}**：${role || goal || '子代理'}`);
      }
    }

    // 通用规则
    lines.push('');
    lines.push('### 子 Agent 调用规则');
    lines.push('');
    lines.push('> **重要**：必须严格遵守以下规则');
    lines.push('');
    lines.push('1. 根据上述「子 Agent 匹配表」，将任务委托给最匹配的子 Agent 处理');
    lines.push('2. 使用 `subagent_call` 工具并指定 `agentName` 来委托任务');
    lines.push('3. 只有当没有匹配的子 Agent 时，才直接调用工具');

    return lines.join('\n');
  }

  /**
   * 从配置文件动态读取子Agent的核心能力
   * 支持 .json 和 .md 格式
   * @private
   * @returns {Promise<string|null>}
   */
  async _getSubAgentCapabilities(name) {
    try {
      const fs = require('fs').promises;
      const path = require('path');
      const agentsDir = path.join(process.cwd(), '.agent', 'agents');

      // 尝试多种文件格式
      const possiblePaths = [
        path.join(agentsDir, `${name}.md`),
        path.join(agentsDir, `${name}.json`),
      ];

      let filePath = null;
      for (const p of possiblePaths) {
        if (
          await fs
            .access(p)
            .then(() => true)
            .catch(() => false)
        ) {
          filePath = p;
          break;
        }
      }

      if (!filePath) {
        return null;
      }

      const content = await fs.readFile(filePath, 'utf-8');

      // .json 格式
      if (filePath.endsWith('.json')) {
        const config = JSON.parse(content);
        return this._extractCapabilitiesFromConfig(config);
      }

      // .md 格式（YAML front matter + markdown）
      if (filePath.endsWith('.md')) {
        return this._extractCapabilitiesFromMd(content);
      }

      return null;
    } catch (e) {
      logger.warn('Agent', `读取子Agent配置 ${name} 失败`, e.message);
      return null;
    }
  }

  /**
   * 从 JSON 配置中提取核心能力
   */
  _extractCapabilitiesFromConfig(config) {
    if (config.instructions) {
      const match = config.instructions.match(/【核心能力】([\s\S]*?)(?=【|$)/);
      if (match) {
        const capabilities = match[1]
          .split('\n')
          .map((line) => line.replace(/^[·\-*]\s*/, '').trim())
          .filter((line) => line && !line.startsWith('你是一个'))
          .slice(0, AGENT_CONFIG.CAPABILITY_MAX_PARTS)
          .join('、');
        return capabilities || config.description;
      }
      return config.description;
    }
    return config.description || null;
  }

  /**
   * 从 .md 文件（YAML front matter）中提取核心能力
   */
  _extractCapabilitiesFromMd(mdContent) {
    // 解析 YAML front matter
    const frontMatterMatch = mdContent.match(/^---\n([\s\S]*?)\n---/);
    if (!frontMatterMatch) {
      return null;
    }

    const frontMatter = frontMatterMatch[1];
    const config = {};

    // 简单解析 YAML front matter
    for (const line of frontMatter.split('\n')) {
      const colonIndex = line.indexOf(':');
      if (colonIndex > 0) {
        const key = line.substring(0, colonIndex).trim();
        let value = line.substring(colonIndex + 1).trim();
        // 移除可能的引号
        if (
          (value.startsWith('"') && value.endsWith('"')) ||
          (value.startsWith("'") && value.endsWith("'"))
        ) {
          value = value.slice(1, -1);
        }
        config[key] = value;
      }
    }
    // 从 description 字段提取能力
    if (config.description) {
      const desc = config.description;
      // 按逗号/顿号分隔
      const parts = desc.split(/[,，、]/).map((s) => s.trim());
      // 取第一部分（通常是最核心的能力描述）
      const firstPart = parts[0];
      // 如果第一部分太长（说明是句子），取前指定长度字符
      if (firstPart.length > AGENT_CONFIG.CAPABILITY_MAX_LENGTH) {
        return firstPart.substring(0, AGENT_CONFIG.CAPABILITY_MAX_LENGTH).trim() + '...';
      }
      // 如果有多个部分，取前指定数量
      if (parts.length > 1) {
        return parts.slice(0, AGENT_CONFIG.CAPABILITY_MAX_PARTS).join('、');
      }
      return firstPart;
    }

    return null;
  }

  _buildSystemPrompt() {
    // 如果没变脏，返回缓存
    if (!this._systemPromptDirty && this._systemPromptCache !== null) {
      return this._systemPromptCache;
    }

    // 使用 builder 构建系统提示词
    this._systemPromptCache = this._systemPromptBuilder.build();
    this._systemPromptDirty = false;
    return this._systemPromptCache;
  }

  /**
   * 使 system prompt 缓存失效
   * @private
   */
  _invalidateSystemPromptCache() {
    this._systemPromptDirty = true;
    // 同时使 builder 中所有部分失效
    this._systemPromptBuilder.invalidateAll();
  }

  /**
   * 注册自定义系统提示词部分（供插件使用）
   * @param {string} name - 部分名称
   * @param {number} priority - 优先级
   * @param {Function} provider - 返回提示词内容的函数
   */
  registerPromptPart(name, priority, provider) {
    this._systemPromptBuilder.register(name, priority, provider);
    this._invalidateSystemPromptCache();
    return this;
  }

  /**
   * 注销系统提示词部分
   * @param {string} name - 部分名称
   */
  unregisterPromptPart(name) {
    this._systemPromptBuilder.unregister(name);
    this._invalidateSystemPromptCache();
    return this;
  }

  /**
   * 使特定系统提示词部分失效
   * @param {string} name - 部分名称
   */
  invalidatePromptPart(name) {
    this._systemPromptBuilder.invalidate(name);
    this._systemPromptDirty = true;
    return this;
  }

  /**
   * 获取工具调用核心规则
   * @private
   */
  _getToolCoreRules() {
    return `## 工具调用核心规则

1. **子 Agent 优先**：任务匹配子 Agent 专业领域时，**必须优先使用** \`subagent_call\` 工具并指定 \`agentName\` 委托给对应子 Agent 处理，而不是直接调用工具。只有当没有匹配的子 Agent 时，才直接调用工具。
2. **必须先调用工具再回复**：当问题需要信息、操作或计算时，必须调用工具获取真实结果后才能回答。禁止在未调用工具的情况下直接给出答案。
3. **禁止编造数据**：不许捏造用户、订单、任务、文件、内容等任何数据。所有数据必须通过工具获取。
4. **工具优先**：可用工具列表会提供，格式为 \`toolName(toolArgs)\`。不确定用哪个工具时，优先调用可能相关的工具。
5. **结果导向**：调用工具后，基于返回结果回答，不要重复工具的内部实现细节。
6. **多步骤任务**：复杂任务拆解为多个工具调用，逐步完成，每步基于结果决定下一步。
7. **步骤未完成必须提示继续**：如果任务需要多步骤操作，在返回前必须明确告知用户当前进度和下一步操作。如果回复内容为空或不完整，必须说明"步骤进行中，请继续"。

## 响应规范

> 直接给出结论或结果，不说"我需要..."、"我建议..."等铺垫话术

- 如果工具返回错误，说明错误原因并给出解决建议
- 如果信息不足，先调用工具获取必要信息，不要假设或猜测
- **重要**：如果任务需要多步骤操作，在回复末尾必须提示用户"请继续"或"是否继续下一步"

## 禁止事项

- 不调用工具就直接回答
- 编造不存在的数据、文件、订单、用户等信息
- 回复含糊不清，让用户无法确定答案是否正确
- **多步骤任务未完成就结束，不提示用户继续**`;
  }

  /**
   * 刷新上下文
   */
  _refreshContext() {
    this.systemPrompt = this._buildSystemPrompt();
    if (this._chatHandler) {
      this._chatHandler.setSystemPrompt(this.systemPrompt);
    }
  }

  /**
   * 初始化聊天处理器
   * @private
   */
  _initChatHandler() {
    let aiClient = null;
    const aiPlugin = this.framework.pluginManager.get('ai');
    if (aiPlugin) {
      aiClient = aiPlugin.getAIClient();
    }

    this._chatHandler = new AgentChatHandler(this, {
      model: this.model,
      provider: this.provider,
      apiKey: this.apiKey,
      baseURL: this.baseURL,
      providerOptions: this.providerOptions,
      // 上下文压缩配置
      maxContextTokens: this.config.maxContextTokens,
      compressionThreshold: this.config.compressionThreshold,
      keepRecentMessages: this.config.keepRecentMessages,
      enableSmartCompress: this.config.enableSmartCompress,
    });

    if (aiClient) {
      this._chatHandler.setAIClient(aiClient);
    }

    // 转发事件
    this._chatHandler.on('message', (msg) => this.emit('message', msg));
    this._chatHandler.on('chunk', (chunk) => this.emit('chunk', chunk));
    this._chatHandler.on('tool-call', (tool) => this.emit('tool-call', tool));
    this._chatHandler.on('tool-result', (result) => this.emit('tool-result', result));
    this._chatHandler.on('error', (err) => this.emit('error', err));

    this._syncTools();
  }

  /**
   * 设置系统提示
   */
  setSystemPrompt(prompt) {
    this._originalPrompt = prompt;
    this.systemPrompt = this._buildSystemPrompt();
    if (this._chatHandler) {
      this._chatHandler.setSystemPrompt(this.systemPrompt);
    }
    return this;
  }

  /**
   * 注册工具到 Agent
   */
  registerTool(tool) {
    this._tools.set(tool.name, tool);
    this._invalidateSystemPromptCache();
    if (this._chatHandler) {
      this._chatHandler.registerTool(tool);
    }
    this._refreshContext();
    return this;
  }

  /**
   * 获取已注册工具
   */
  getTools() {
    return Array.from(this._tools.values());
  }

  /**
   * 同步框架中的工具到 Agent
   * @private
   */
  _syncTools() {
    if (this.framework.toolRegistry.size() > 0) {
      for (const tool of this.framework.getTools()) {
        if (!this._tools.has(tool.name)) {
          this.registerTool(tool);
        }
      }
    }
  }

  /**
   * 注册子Agent
   * @param {string} name - 子Agent名称
   * @param {Agent} agent - 子Agent实例
   * @param {string} role - 角色描述
   * @param {string} goal - 目标描述
   */
  registerSubAgent(name, agent, role, goal) {
    this._subAgents.set(name, { agent, role, goal });
    this._invalidateSystemPromptCache();
    this._refreshContext();
    return this;
  }

  /**
   * 注销子Agent
   */
  unregisterSubAgent(name) {
    this._subAgents.delete(name);
    this._invalidateSystemPromptCache();
    this._refreshContext();
    return this;
  }

  /**
   * 获取所有子Agent
   */
  getSubAgents() {
    return this._subAgents;
  }

  /**
   * 获取待处理的调度通知并清除（下次不再重复显示）
   */
  _getAndClearSchedulerNotifications() {
    try {
      const scheduler = this.framework.pluginManager.get('scheduler');
      if (scheduler && scheduler.instance && scheduler.instance.getPendingNotifications) {
        const results = scheduler.instance.getPendingNotifications();
        if (results.length > 0) {
          // 使用常量替代硬编码数字
          const notifications = results.slice(-AGENT_CONFIG.MAX_NOTIFICATIONS).reverse();
          // 清除已发送的通知
          if (scheduler.instance.clearDeliveredNotifications) {
            scheduler.instance.clearDeliveredNotifications(notifications.length);
          }
          return notifications;
        }
      }
    } catch (err) {
      logger.warn('Agent', '获取调度通知失败', err.message);
    }
    return [];
  }

  /**
   * 获取待处理的思考结果并清除
   */
  _getAndClearThinkNotifications() {
    try {
      const think = this.framework.pluginManager.get('think');
      if (think && think.instance && think.instance.getPendingThoughts) {
        const thoughts = think.instance.getPendingThoughts();
        if (thoughts.length > 0) {
          // 使用常量替代硬编码数字
          return thoughts.slice(-AGENT_CONFIG.MAX_NOTIFICATIONS).reverse();
        }
      }
    } catch (err) {
      logger.warn('Agent', '获取思考通知失败', err.message);
    }
    return [];
  }

  /**
   * 获取所有待处理的系统通知（调度 + 思考）
   */
  _getAllPendingNotifications() {
    const notifications = [];

    // 调度通知
    const schedulerNotifs = this._getAndClearSchedulerNotifications();
    for (const n of schedulerNotifs) {
      notifications.push(
        `【定时任务通知】\n任务: ${n.taskName || n.taskId}\n执行时间: ${n.executedAt}\n结果: ${n.result || n.action || '执行完成'}`
      );
    }

    // 思考通知
    const thinkNotifs = this._getAndClearThinkNotifications();
    for (const t of thinkNotifs) {
      notifications.push(
        `【主动思考】\n模式: ${t.mode}\n主题: ${t.topic}\n结果: ${t.result || '思考完成'}`
      );
    }

    return notifications;
  }

  /**
   * 发送消息
   */
  async chat(message, options = {}) {
    if (this._status === 'error') {
      this._status = 'idle';
    }

    this._status = 'busy';
    this.emit('status', { status: 'busy' });

    try {
      // 检查是否有待处理的系统通知（调度 + 思考）
      const notifications = this._getAllPendingNotifications();
      let enhancedMessage = message;
      if (notifications.length > 0) {
        enhancedMessage = `【系统通知】\n${notifications.join('\n\n')}\n\n---\n用户消息: ${message}`;
      }

      this._syncTools();

      // 通过 handler 的 enqueue 处理（自动排队）
      const result = await this._chatHandler.chat(enhancedMessage, options);

      this._status = 'idle';
      this.emit('status', { status: 'idle' });

      return result;
    } catch (err) {
      this._status = 'error';
      logger.error('Agent', `chat 方法执行失败: ${err.message}`, { stack: err.stack });
      this.emit('status', { status: 'error', error: err.message });
      throw err;
    }
  }

  /**
   * 推送消息（自动继承当前 sessionId 上下文，自动排队）
   * 工具中调用此方法，自动带上当前执行上下文的 sessionId
   * 如果 agent 忙碌，消息会进入队列等待
   * @param {string|Object} message - 消息
   * @param {Object} options - 选项 { maxSteps }
   * @returns {Promise<{success: boolean, message: string, stepCount: number}>}
   */
  async pushMessage(message, options = {}) {
    // 自动从执行上下文获取 sessionId
    const ctx = this.framework.getExecutionContext();
    if (ctx?.sessionId && !options.sessionId) {
      options.sessionId = ctx.sessionId;
    }

    // 直接调用 chat，由 handler 的 enqueue 处理排队
    return this.chat(message, options);
  }

  /**
   * 发送消息（流式）
   */
  async *chatStream(message, options = {}) {
    if (this._status === 'busy') {
      throw new Error('Agent is busy');
    }

    // 允许从 error 状态重试
    if (this._status === 'error') {
      this._status = 'idle';
    }

    this._status = 'busy';
    this.emit('status', { status: 'busy' });

    try {
      // 检查是否有待处理的系统通知（调度 + 思考）
      const notifications = this._getAllPendingNotifications();
      let enhancedMessage = message;
      if (notifications.length > 0) {
        enhancedMessage = `【系统通知】\n${notifications.join('\n\n')}\n\n---\n用户消息: ${message}`;
      }

      this._syncTools();

      yield* this._chatHandler.chatStream(enhancedMessage, options);
      this._status = 'idle';
      this.emit('status', { status: 'idle' });
    } catch (err) {
      this._status = 'error';
      logger.error('Agent', `chatStream 方法执行失败: ${err.message}`, { stack: err.stack });
      this.emit('status', { status: 'error', error: err.message });

      throw err;
    }
  }

  /**
   * 设置元数据
   */
  setMetadata(keyOrObj, value) {
    if (typeof keyOrObj === 'string') {
      this._metadata.set(keyOrObj, value);
    } else if (keyOrObj && typeof keyOrObj === 'object') {
      for (const [key, val] of Object.entries(keyOrObj)) {
        this._metadata.set(key, val);
      }
    }
    this._invalidateSystemPromptCache();
    this._refreshContext();
    return this;
  }

  /**
   * 获取元数据
   */
  getMetadata(key) {
    return this._metadata.get(key);
  }

  /**
   * 删除元数据
   */
  deleteMetadata(key) {
    this._metadata.delete(key);
    this._refreshContext();
    return this;
  }

  /**
   * 清空元数据
   */
  clearMetadata() {
    this._metadata.clear();
    this._refreshContext();
    return this;
  }

  /**
   * 清空对话历史
   */
  clearHistory() {
    if (this._chatHandler) {
      this._chatHandler.clearHistory();
    }
    return this;
  }

  /**
   * 获取状态
   */
  getStatus() {
    return this._status;
  }

  /**
   * 获取Agent ID
   * @returns {string} Agent名称
   */
  getCurrentAgentId() {
    return this.name;
  }

  /**
   * 重置状态（从卡住状态恢复）
   */
  resetStatus() {
    this._status = 'idle';
    this.emit('status', { status: 'idle' });
    return this;
  }

  /**
   * 销毁 Agent
   */
  destroy() {
    if (this._chatHandler) {
      this._chatHandler.destroy();
    }
    this._tools.clear();
    this.removeAllListeners();
    this.emit('destroyed');
    logger.info('Agent', `Agent "${this.name}" 已销毁`);
  }
}

module.exports = { Agent };
