/**
 * ExplorerLoop - 主自主循环，决定并执行操作
 */

const { Plugin } = require('../../src/core/plugin-base')
const { logger } = require('../../src/utils/logger')
const { Agent } = require('../../src/core/agent')
const { StepExecutor } = require('../../src/capabilities/workflow-engine')
const { SystemPrompts, ThinkModePrompts, FreeThinkPrompts } = require('./constants')

const log = logger.child('Ambient:ExplorerLoop')

class ExplorerLoop {
  constructor(goalManager, reflector, framework, config) {
    this._goalManager = goalManager
    this._reflector = reflector
    this._framework = framework
    this._config = config
    this._running = false
    this._timer = null
    this._lastActionTime = 0
    this._tickCount = 0
    this._recentActivities = []
    this._stepExecutor = new StepExecutor(framework)
    this._ambientAgent = null
    this._initAmbientAgent()
  }

  // ============================================================================
  // 生命周期
  // ============================================================================

  /**
   * 初始化 Ambient 专用子 Agent
   */
  _initAmbientAgent() {
    const aiPlugin = this._framework.pluginManager?.get('ai')
    const llmConfig = aiPlugin ? aiPlugin.getConfig() : {}

    this._ambientAgent = new Agent(this._framework, {
      name: 'ambient-worker',
      systemPrompt: SystemPrompts.ambientWorker,
      model: llmConfig.model,
      provider: llmConfig.provider,
      apiKey: llmConfig.apiKey,
      baseURL: llmConfig.baseURL
    })

    // 注册到主 agent（如果主 agent 已存在）
    if (this._framework._mainAgent) {
      this._registerAmbientWorker(this._framework._mainAgent)
    } else {
      // 等待主 agent 创建
      this._framework.once('agent:created', (agent) => {
        if (this._framework._mainAgent && agent === this._framework._mainAgent) {
          this._registerAmbientWorker(agent)
        }
      })
    }
  }

  /**
   * 注册 ambient-worker 到主 agent
   */
  _registerAmbientWorker(agent) {
    if (!this._ambientAgent) return
    agent.registerSubAgent(
      'ambient-worker',
      this._ambientAgent,
      '后台任务执行器',
      '执行需要 AI 能力的后台任务'
    )
    log.info('ambient-worker subagent registered')
  }

  /**
   * 启动探索循环
   */
  start() {
    if (this._running) return
    this._running = true
    this._scheduleNext()
  }

  /**
   * 停止探索循环
   */
  stop() {
    this._running = false
    if (this._timer) {
      clearTimeout(this._timer)
      this._timer = null
    }
  }

  /**
   * 暂停探索循环
   */
  pause() {
    this._running = false
    if (this._timer) {
      clearTimeout(this._timer)
      this._timer = null
    }
  }

  /**
   * 恢复探索循环
   */
  resume() {
    if (!this._running) {
      this._running = true
      this._scheduleNext()
    }
  }

  /**
   * 检查是否运行中
   */
  isRunning() {
    return this._running
  }

  /**
   * 获取状态
   */
  getStatus() {
    return {
      running: this._running,
      tickCount: this._tickCount,
      lastTick: this._lastActionTime ? new Date(this._lastActionTime) : null,
      recentActivities: this._recentActivities.slice(-10),
      activeGoals: this._goalManager.getActiveGoals().length,
      pendingGoals: this._goalManager.getPendingGoals().length
    }
  }

  // ============================================================================
  // 主循环
  // ============================================================================

  _scheduleNext() {
    if (!this._running) return
    this._timer = setTimeout(() => this._tick(), this._config.tickInterval)
  }

  async _tick() {
    if (!this._running) return

    // 如果处于嵌套执行上下文中，跳过此tick
    try {
      if (this._framework.getExecutionContext) {
        const ctx = this._framework.getExecutionContext()
        if (ctx && ctx.id) {
          // 跳过此tick，重新调度
          this._scheduleNext()
          return
        }
      }
    } catch (e) {
      // getExecutionContext可能不存在，继续执行
    }

    this._tickCount++

    try {
      await this._processGoals()
    } catch (err) {
      log.error('Tick错误:', err.message)
      this._addActivity('error', { message: err.message })
    }
    this._lastActionTime = Date.now()
    // 调度下一次tick
    this._scheduleNext()
  }

  async _processGoals() {
    const activeGoals = this._goalManager.getActiveGoals()
    //log.info(`[ExplorerLoop] _processGoals: ${activeGoals.length} 个活跃目标, _lastActionTime=${this._lastActionTime}, cooldown=${this._config.cooldownPeriod}`)

    for (const goal of activeGoals) {
      // 检查冷却时间
      const timeSinceLastAction = Date.now() - this._lastActionTime
      //log.info(`[ExplorerLoop] 检查 goal=${goal.id}, timeSinceLastAction=${timeSinceLastAction}`)
      if (timeSinceLastAction < this._config.cooldownPeriod) {
        //log.info(`[ExplorerLoop] 跳过 goal=${goal.id}, 还在冷却中`)
        continue
      }

      // 检查目标是否有未处理的事件
      const hasNewEvents = goal.eventsReceived && goal.eventsReceived.length > 0

      // 检查是否是事件驱动目标
      const isEventDriven = goal.conditions?.events && goal.conditions.events.length > 0

      // 事件驱动目标：只有在新事件时才执行 actions
      if (isEventDriven && !hasNewEvents) {
        //log.info(`[ExplorerLoop] 跳过 goal=${goal.id}, 事件驱动但无新事件`)
        continue
      }

      log.info(`[ExplorerLoop] 开始执行 goal=${goal.id}, hasNewEvents=${hasNewEvents}, actions=${goal.actions?.length}`)

      // 获取下一个操作（跳过已完成的 actions）
      if (goal.actions && goal.actions.length > 0) {
        // 过滤掉已完成的 actions
        const pendingActions = goal.actions.filter(a => !a.completed)
        if (pendingActions.length === 0) {
          log.info(`[ExplorerLoop] goal=${goal.id} 所有 actions 已完成，等待下一事件`)
          this._resetGoalForNextEvent(goal)
          continue
        }

        // 如果有多个 action，按顺序执行所有 action
        if (goal.actions.length > 1) {
          const eventData = hasNewEvents ? goal.eventsReceived[0] : null
          log.info(`[ExplorerLoop] 执行 ${goal.actions.length} 个 actions, eventData=${JSON.stringify(eventData?.data?.subject || 'none')}`)
          const results = await this._executeAllActions(goal.actions, eventData)
          log.info(`[ExplorerLoop] actions 执行完成, results.length=${results.length}`)

          // 最后一个结果用于评估
          const lastResult = results.length > 0 ? results[results.length - 1].result : null

          // 评估结果
          const outcome = this._reflector.evaluateOutcome(goal, lastResult)

          if (outcome.goalComplete && !isEventDriven) {
            // 非事件驱动目标可以完成
            this._goalManager.completeGoal(goal.id)
            this._addActivity('goal_completed', { goalId: goal.id, attempts: goal.attempts })
            this._notifyUser('目标完成', `目标 "${goal.title}" 已完成（尝试次数：${goal.attempts}）`, 'success')
          } else if (!outcome.shouldContinue && !isEventDriven) {
            // 非事件驱动目标可以失败
            this._goalManager.failGoal(goal.id, '达到最大尝试次数')
            this._addActivity('goal_failed', { goalId: goal.id, reason: '达到最大尝试次数' })
            this._notifyUser('目标失败', `目标 "${goal.title}" 失败：达到最大尝试次数`, 'error')
          } else {
            // 事件驱动目标：不论结果如何，都重置并继续等待下一事件
            this._addActivity('actions_completed', { goalId: goal.id, actionCount: results.length })

            // 检查所有 actions 是否都已完成
            const allDone = goal.actions.every(a => a.completed)
            if (allDone && !goal.persistent) {
              // 一次性目标：所有 actions 完成后直接完成
              this._goalManager.completeGoal(goal.id)
              this._addActivity('goal_completed', { goalId: goal.id, reason: '一次性任务执行完成' })
              this._notifyUser('目标完成', `目标 "${goal.title}" 已完成`, 'success')
            } else if (hasNewEvents) {
              // 持久化目标且有新事件，重置 actions
              this._resetGoalForNextEvent(goal)
            }
          }
          continue
        }

        // 单个 action，使用原有逻辑
        const action = goal.actions.find(a => !a.completed)
        if (!action) {
          // 所有 actions 已完成
          log.info(`[ExplorerLoop] goal=${goal.id} 所有 actions 已完成`)
          const allDone = goal.actions.every(a => a.completed)
          if (allDone && !goal.persistent) {
            // 一次性目标：所有 actions 完成后直接完成
            this._goalManager.completeGoal(goal.id)
            this._addActivity('goal_completed', { goalId: goal.id, reason: '一次性任务执行完成' })
            this._notifyUser('目标完成', `目标 "${goal.title}" 已完成`, 'success')
          } else {
            // 持久化目标：等待下一事件
            this._resetGoalForNextEvent(goal)
          }
          continue
        }

        // 循环检测（仅用于非事件驱动的操作）
        if (!hasNewEvents && this._reflector.checkLoopDetection(goal, action.id)) {
          this._addActivity('goal_failed', { goalId: goal.id, reason: '检测到循环' })
          // 通知用户目标失败
          this._notifyUser('目标失败', `目标 "${goal.title}" 失败：检测到循环（同一操作连续重复）`, 'error')
          continue
        }

        // 执行操作
        const result = await this._executeAction(action, hasNewEvents ? goal.eventsReceived[0] : null)

        // 标记 action 为已完成
        action.completed = true

        // 评估结果
        const outcome = this._reflector.evaluateOutcome(goal, result)

        if (outcome.goalComplete) {
          this._goalManager.completeGoal(goal.id)
          this._addActivity('goal_completed', { goalId: goal.id, attempts: goal.attempts })
          // 通知用户目标完成
          this._notifyUser('目标完成', `目标 "${goal.title}" 已完成（尝试次数：${goal.attempts}）`, 'success')
        } else if (!outcome.shouldContinue) {
          this._goalManager.failGoal(goal.id, '达到最大尝试次数')
          this._addActivity('goal_failed', { goalId: goal.id, reason: '达到最大尝试次数' })
          // 通知用户目标失败
          this._notifyUser('目标失败', `目标 "${goal.title}" 失败：达到最大尝试次数`, 'error')
        } else {
          this._addActivity('action_executed', { goalId: goal.id, action: action.id, hasEvents: hasNewEvents })

          // 检查所有 actions 是否都已完成
          const allDone = goal.actions.every(a => a.completed)
          if (allDone && !goal.persistent) {
            // 一次性目标：所有 actions 完成后直接完成
            this._goalManager.completeGoal(goal.id)
            this._addActivity('goal_completed', { goalId: goal.id, reason: '一次性任务执行完成' })
            this._notifyUser('目标完成', `目标 "${goal.title}" 已完成`, 'success')
          } else if (hasNewEvents) {
            // 持久化目标且有新事件，重置 actions
            this._resetGoalForNextEvent(goal)
          }
        }
      }
    }

    // 激活满足条件的待处理目标
    const pendingGoals = this._goalManager.getPendingGoals()
    for (const goal of pendingGoals) {
      // 自动激活没有条件的目标
      // 有条件的目标会在事件触发时被 EventWatcher 自动激活
      if (!goal.conditions || Object.keys(goal.conditions).length === 0) {
        this._goalManager.activateGoal(goal.id)
        this._addActivity('goal_activated', { goalId: goal.id })
      } else {
        // 有条件的目标，立即激活以便开始监听事件
        this._goalManager.activateGoal(goal.id)
        this._addActivity('goal_activated', { goalId: goal.id, reason: '事件监听目标已激活' })
      }
    }
  }

  /**
   * 重置目标以处理下一事件（仅用于持久化目标）
   */
  _resetGoalForNextEvent(goal) {
    goal.eventsReceived = []
    // 重置所有 actions 的完成标记
    for (const action of goal.actions) {
      action.completed = false
    }
    this._goalManager.updateGoal(goal.id, { eventsReceived: [] })
  }

  // ============================================================================
  // Action 执行
  // ============================================================================

  /**
   * 执行单个 action
   * @param {Object} action - action 配置
   * @param {Object} eventData - 事件数据
   * @param {Object} context - 执行上下文（包含 stepOutputs 等）
   * @returns {Promise<Object>} 执行结果
   */
  async _executeAction(action, eventData = null, context = null) {
    if (!this._framework) {
      return { success: false, error: '框架不可用' }
    }

    try {
      // 如果没有提供 context，创建一个新的
      if (!context) {
        context = {
          input: {},
          variables: {
            _event: eventData?.data || eventData || null,
            _eventRaw: eventData || null,
            _action: action
          },
          lastResult: null
        }
      } else {
        // 更新 context 中的 _action
        context.variables._action = action
      }

      // 将 action 转换为 step 配置
      const step = this._actionToStep(action)

      // 将 _event 注入到 step.args 中，供工具使用
      // 统一使用 eventData.data 作为事件数据源
      const effectiveEventData = eventData || context?.variables?._eventRaw
      if (effectiveEventData) {
        step.args = step.args || {}
        // 从 eventData.data 中提取邮件对象（email 事件的数据在 data.email 中）
        const eventObj = effectiveEventData?.data?.email || effectiveEventData?.data || effectiveEventData
        // 统一注入到 _event，让 ${event.xxx} 可以直接访问
        step.args._event = eventObj
        step.args._eventRaw = effectiveEventData
      }

      // 解析 step.args 中的变量引用（支持 ${actionId.output} 格式）
      if (step.args) {
        step.args = this._resolveActionArgs(step.args, context)
      }
      if (step.input) {
        step.input = this._resolveActionArgs(step.input, context)
      }

      // message 和 think 类型使用专用子 agent 执行
      if (step.type === 'message' || step.type === 'think') {
        return await this._executeWithAmbientAgent(step, context)
      }

      // 工具类型
      if (step.type === 'tool') {
        if (step.tool) {
          // 工具已指定，通过 ext_call 执行（plugin 可选）
          const extResult = await this._executeViaExtCall(step.tool, step.args || {}, step.plugin)
          if (extResult && (extResult.success !== false || !extResult.error?.includes('not found'))) {
            return extResult
          }
          log.info(`[ExplorerLoop] ext_call 回退到 StepExecutor: ${step.tool}`)
        } else {
          // 工具未指定，让 LLM 选择工具
          return await this._executeWithAmbientAgent(step, context)
        }
      }

      const result = await this._stepExecutor.executeStep(step, context)
      return result
    } catch (err) {
      return { success: false, error: err.message }
    }
  }

  /**
   * 解析 action 参数中的变量引用
   * 支持 ${actionId.output}、${actionId.output.field} 和 ${event.xxx} 格式
   */
  _resolveActionArgs(args, context) {
    if (!args || typeof args !== 'object') return args

    const stepOutputs = context.variables._stepOutputs || {}
    const eventData = context.variables._event || {}

    const resolved = {}
    for (const [key, value] of Object.entries(args)) {
      resolved[key] = this._resolveActionValue(value, stepOutputs, eventData)
    }
    return resolved
  }

  /**
   * 解析单个值中的 ${actionId.output} 引用和 ${event.xxx} 引用
   */
  _resolveActionValue(value, stepOutputs, eventData) {
    if (typeof value === 'string') {
      // 处理 ${actionId.output} 和 ${actionId.output.field} 格式
      const result = value.replace(/\$\{([^}]+)\}/g, (match, path) => {
        if (path === 'output' || path === 'result') {
          // {{result}} 引用上一步结果
          return stepOutputs._lastResult ?? match
        }
        if (path.startsWith('event.')) {
          // ${event.xxx} 引用事件数据
          let eventPath = path.replace(/^event\./, '')
          // 直接在 eventData 中查找（最常见的情况）
          let val = this._getNestedValue(eventData, eventPath)
          if (val !== undefined) return val
          // 兼容：如果 eventData.data 存在，尝试从中查找
          if (eventData?.data) {
            val = this._getNestedValue(eventData.data, eventPath)
            if (val !== undefined) return val
          }
          // 兼容：如果 eventData.email 存在（邮件事件，字段直接在 email 对象下），查找 eventData.email
          if (eventData?.email) {
            val = this._getNestedValue(eventData.email, eventPath)
            if (val !== undefined) return val
          }
          // 兼容：如果 eventData.data.email 存在（嵌套的邮件事件），直接在 email 对象中查找
          if (eventData?.data?.email) {
            val = this._getNestedValue(eventData.data.email, eventPath)
            if (val !== undefined) return val
          }
          return match
        }
        if (path === 'event') {
          // ${event} 引用整个事件数据对象
          return eventData ?? match
        }
        if (path.includes('.')) {
          // ${actionId.output.field} 格式
          const [actionId, ...fieldParts] = path.split('.')
          if (actionId === 'result' || actionId === 'output') {
            // {{result.field}} 格式
            const val = this._getNestedValue(stepOutputs._lastResult, fieldParts.join('.'))
            return val !== undefined ? val : match
          }
          const actionOutput = stepOutputs[actionId]
          if (actionOutput !== undefined) {
            const val = this._getNestedValue(actionOutput, fieldParts.join('.'))
            return val !== undefined ? val : match
          }
        } else {
          // ${actionId.output} 格式
          const actionOutput = stepOutputs[path]
          if (actionOutput !== undefined) return actionOutput
        }
        return match
      })
      return result
    } else if (Array.isArray(value)) {
      return value.map(v => this._resolveActionValue(v, stepOutputs, eventData))
    } else if (typeof value === 'object' && value !== null) {
      const resolved = {}
      for (const [k, v] of Object.entries(value)) {
        resolved[k] = this._resolveActionValue(v, stepOutputs, eventData)
      }
      return resolved
    }
    return value
  }

  _getNestedValue(obj, path) {
    if (!obj) return undefined
    const parts = path.split('.')
    let current = obj
    for (const part of parts) {
      if (current === null || current === undefined) return undefined
      current = current[part]
    }
    return current
  }

  /**
   * 按顺序执行所有 actions
   * @param {Array} actions - action 数组
   * @param {Object} eventData - 事件数据
   * @returns {Promise<Array>} 所有执行结果
   */
  async _executeAllActions(actions, eventData = null) {
    const results = []
    const stepOutputs = {}

    const context = {
      input: {},
      variables: {
        _event: eventData?.data || eventData || null,
        _eventRaw: eventData || null,
        _stepOutputs: stepOutputs
      },
      lastResult: null
    }

    for (const action of actions) {
      // 跳过已完成的 action
      if (action.completed) {
        continue
      }

      // 执行前更新 stepOutputs
      context.variables._stepOutputs = stepOutputs

      const result = await this._executeAction(action, eventData, context)

      // 标记 action 为已完成
      action.completed = true

      // 保存结果：使用 action id 作为键
      if (action.id) {
        stepOutputs[action.id] = result
      }
      // 同时保存为 _lastResult 供 {{result}} 引用
      stepOutputs._lastResult = result
      context.lastResult = result

      results.push({ actionId: action.id, result })

      // 如果执行失败，停止执行
      if (result && result.success === false) {
        break
      }
    }

    return results
  }

  /**
   * 获取所有扩展工具的描述（供 LLM 选择）
   */
  _getExtensionsDescription() {
    const extExec = this._framework.pluginManager?.get('extension-executor')
    if (!extExec || !extExec._buildExtensionsDescription) {
      return '无可用的扩展工具'
    }
    const desc = extExec._buildExtensionsDescription()
    return desc || '无可用的扩展工具'
  }

  /**
   * 使用 ambient 子 agent 执行 AI 相关操作
   */
  async _executeWithAmbientAgent(step, context) {
    if (!this._ambientAgent) {
      return { success: false, error: 'Ambient agent 未初始化' }
    }

    if (step.type === 'message') {
      let content = step.content || ''
      content = this._stepExecutor._resolveValue(content, context)

      if (context.variables._event) {
        content = `${content}\n\n[事件上下文: ${JSON.stringify(context.variables._event)}]`
      }

      try {
        const result = await this._ambientAgent.pushMessage(content)
        return { success: true, result }
      } catch (err) {
        return { success: false, error: err.message }
      }
    }

    if (step.type === 'think') {
      const thinkPlugin = this._framework.pluginManager?.get('think')
      if (!thinkPlugin) {
        return { success: false, error: '思考插件不可用' }
      }

      let topic = step.topic || 'Ambient代理反思'
      topic = this._stepExecutor._resolveValue(topic, context)

      if (context.variables._event) {
        topic = `${topic}\n\n[事件上下文: ${JSON.stringify(context.variables._event)}]`
      }

      try {
        const result = await thinkPlugin._triggerThinking({
          topic,
          mode: step.mode || 'reflect',
          depth: step.depth || 2
        })
        return result
      } catch (err) {
        return { success: false, error: err.message }
      }
    }

    if (step.type === 'tool') {
      // 如果工具已指定，直接执行
      if (step.tool) {
        return await this._executeViaExtCall(step.tool, step.args || {})
      }

      // 工具未指定，让 LLM 根据上下文选择
      const eventData = context.variables._event
      let eventContextStr = '无事件上下文'
      if (eventData) {
        eventContextStr = `**事件数据结构（从 event.xxx 引用任何字段）**:\n\`\`\`json\n${JSON.stringify(eventData, null, 2)}\n\`\`\``
      }

      // 上一步的输出结果（可用于引用）
      const lastResult = context.variables._stepOutputs?._lastResult
      let lastResultStr = ''
      if (lastResult) {
        lastResultStr = `**上一步结果（从 result.xxx 引用任何字段）**:\n\`\`\`json\n${JSON.stringify(lastResult, null, 2)}\n\`\`\``
      }

      const extensionsInfo = this._getExtensionsDescription()

      const prompt = `你是 Ambient Agent，需要为以下目标选择一个合适的工具来执行。

**目标**: ${step.name || '根据事件自动决定执行什么操作'}

${eventContextStr}

${lastResultStr}

## 可用的扩展工具及其参数要求：
${extensionsInfo}

## 如何决定参数传递：
1. 查看上方的**事件数据结构**，找到需要的字段
2. 查看工具的**参数要求**（parameters 或 properties 下列出的字段）
3. 根据字段名称和含义，判断应该传递什么值
4. 使用 \${event.xxx} 或 \${result.xxx} 引用对应字段

**示例**：
如果事件中有 \`from: "user@example.com"\`，而工具需要 \`to\` 参数，
则传递 \`"to": "\${event.from}"\`

**返回格式**：
\`\`\`json
{
  "plugin": "插件名",
  "tool": "工具名",
  "args": {
    "参数名": "\${event.字段名}"
  }
}
\`\`\`

如果不需要执行任何工具，返回：\`\`\`json
{"plugin": null, "tool": null, "args": {}}
\`\`\`

请直接返回 JSON 代码块。`

      try {
        const response = await this._ambientAgent.pushMessage(prompt)
        const responseText = typeof response === 'string' ? response : JSON.stringify(response)

        // 尝试解析 LLM 返回的 JSON
        let toolChoice = null
        try {
          // 提取 JSON（可能在 markdown 代码块中）
          const jsonMatch = responseText.match(/```json\n?([\s\S]*?)\n?```/) || responseText.match(/(\{[\s\S]*\})/)
          if (jsonMatch) {
            toolChoice = JSON.parse(jsonMatch[1])
          }
        } catch (e) {
          log.warn(`[ExplorerLoop] 解析 LLM 工具选择失败: ${e.message}`)
          return { success: false, error: `LLM 返回格式错误: ${responseText.slice(0, 200)}` }
        }

        if (toolChoice && toolChoice.tool) {
          log.info(`[ExplorerLoop] LLM 选择工具: plugin=${toolChoice.plugin}, tool=${toolChoice.tool}, args=${JSON.stringify(toolChoice.args)}`)
          return await this._executeViaExtCall(toolChoice.tool, toolChoice.args || {}, toolChoice.plugin)
        } else {
          return { success: true, message: 'LLM 选择不执行任何工具', response: responseText }
        }
      } catch (err) {
        return { success: false, error: err.message }
      }
    }

    return { success: false, error: `未知 AI 操作类型: ${step.type}` }
  }

  /**
   * 将 action 转换为 step 配置
   */
  _actionToStep(action) {
    const step = {
      id: action.id || `action_${Date.now()}`,
      type: action.type,
      name: action.name || action.id,
      plugin: action.plugin  // 插件名称（如 email, gate-trading）
    }

    switch (action.type) {
      case 'tool':
        step.tool = action.name
        step.args = action.args || {}
        break
      case 'message':
        step.content = action.content || ''
        break
      case 'think':
        step.topic = action.topic || 'Ambient代理反思'
        step.mode = action.mode || 'reflect'
        step.depth = action.depth || 2
        break
    }

    return step
  }

  // ============================================================================
  // 辅助方法
  // ============================================================================

  /**
   * 通过 ext_call 执行插件工具
   * 支持所有通过 extension-executor 注册的工具：email, mcp, python, extension 等
   * @param {string} toolName - 工具名称（如 email_auto_reply, mcp_github_search）
   * @param {Object} args - 工具参数
   * @param {string} [plugin] - 插件名称（如指定则直接使用，否则从 toolName 推断）
   * @returns {Promise<Object>} 执行结果
   */
  async _executeViaExtCall(toolName, args, plugin) {
    // 尝试多种可能的插件前缀
    const pluginPrefixes = [
      ['email_', 'email'],
      ['scheduler_', 'scheduler'],
      ['memory_', 'memory'],
      ['web_', 'web'],
      ['shell_', 'shell'],
      ['python_', 'python'],
      ['think_', 'think'],
      ['mcp_', 'mcp'],
      ['ext_', 'extension'],
    ]

    // 如果指定了 plugin，直接使用
    if (plugin) {
      log.info(`[ExplorerLoop] 通过 ext_call 执行: plugin=${plugin}, tool=${toolName}`)
      try {
        const result = await this._framework.executeTool('ext_call', {
          plugin,
          tool: toolName,
          args
        })
        return result
      } catch (err) {
        log.warn(`[ExplorerLoop] ext_call 错误: ${err.message}`)
        return { success: false, error: err.message }
      }
    }

    // 先尝试从工具名推断的插件
    const inferredPlugin = this._inferPluginName(toolName)
    log.info(`[ExplorerLoop] 通过 ext_call 执行: plugin=${inferredPlugin}, tool=${toolName}`)

    try {
      const result = await this._framework.executeTool('ext_call', {
        plugin: inferredPlugin,
        tool: toolName,
        args
      })
      return result
    } catch (err) {
      // 如果错误不是 "not found"，返回错误
      if (!err.message.includes("not found") && !err.message.includes("不存在")) {
        log.warn(`[ExplorerLoop] ext_call 错误: ${err.message}`)
        return { success: false, error: err.message }
      }
      // 否则尝试其他可能的插件
    }

    // 尝试其他可能的插件前缀
    for (const [prefix, extPlugin] of pluginPrefixes) {
      if (toolName.startsWith(prefix) && extPlugin !== inferredPlugin) {
        try {
          const result = await this._framework.executeTool('ext_call', {
            plugin: extPlugin,
            tool: toolName,
            args
          })
          log.info(`[ExplorerLoop] ext_call 成功: plugin=${extPlugin}, tool=${toolName}`)
          return result
        } catch (err) {
          continue
        }
      }
    }

    // 尝试不带前缀的工具名（某些扩展可能用其他命名）
    const shortName = toolName.replace(/^[a-z]+_/, '')
    for (const [prefix, plugin] of pluginPrefixes) {
      try {
        const result = await this._framework.executeTool('ext_call', {
          plugin,
          tool: shortName,
          args
        })
        log.info(`[ExplorerLoop] ext_call 成功（短名）: plugin=${plugin}, tool=${shortName}`)
        return result
      } catch (err) {
        continue
      }
    }

    return { success: false, error: `工具 ${toolName} 未找到` }
  }

  /**
   * 从工具名称推断插件名称
   * @param {string} toolName - 工具名称
   * @returns {string} 插件名称
   */
  _inferPluginName(toolName) {
    // 常见插件工具前缀映射
    const pluginPrefixes = {
      email_: 'email',
      scheduler_: 'scheduler',
      memory_: 'memory',
      web_: 'web',
      shell_: 'shell',
      python_: 'python',
      think_: 'think',
      mcp_: 'mcp',
      ext_: 'extension',
    }

    for (const [prefix, plugin] of Object.entries(pluginPrefixes)) {
      if (toolName.startsWith(prefix)) {
        return plugin
      }
    }

    // 默认返回 'extension'（extension-executor 默认命名空间）
    return 'extension'
  }

  _getActiveAgent() {
    if (this._framework._mainAgent) {
      return this._framework._mainAgent
    }
    const agents = this._framework._agents || []
    return agents.length > 0 ? agents[agents.length - 1] : null
  }

  _addActivity(type, data) {
    this._recentActivities.push({
      type,
      data,
      timestamp: new Date()
    })
    // 只保留最近50条活动记录
    if (this._recentActivities.length > 50) {
      this._recentActivities = this._recentActivities.slice(-50)
    }
  }

  /**
   * 通知用户（通过事件发送给消息插件）
   */
  _notifyUser(title, message, level = 'info') {
    if (!this._framework) return

    // 获取目标相关的sessionId（如果有）
    let sessionId = null
    const sessionPlugin = this._framework.pluginManager.get('session')
    if (sessionPlugin) {
      const sessions = sessionPlugin.listSessions()
      if (sessions.length > 0) {
        // 取最新的会话
        sessions.sort((a, b) => new Date(b.lastActive).getTime() - new Date(a.lastActive).getTime())
        sessionId = sessions[0].id
      }
    }

    // 发送统一的通知事件
    this._framework.emit('notification', {
      title,
      message,
      source: 'ambient',
      level,  // 'info' | 'warning' | 'success' | 'error'
      sessionId,
      timestamp: new Date()
    })

    log.info(`${title}: ${message}`)
  }
}

module.exports = { ExplorerLoop }
