/**
 * SubAgent 子Agent插件
 * 创建具有独立工具集的子Agent，用于分工处理不同领域的任务
 */

const fs = require('fs')
const path = require('path')
const { Plugin } = require('../src/core/plugin-base')
const { logger } = require('../src/utils/logger')
const log = logger.child('SubAgent')
const { z } = require('zod')
const { Agent } = require('../src/core/agent')

class SubAgentPlugin extends Plugin {
  constructor(config = {}) {
    super()
    this.name = config.name
    this.version = '1.0.0'
    this.description = config.description || `子Agent: ${config.name}`
    this.priority = 10

    this.system = true 

    this.role= config.role || config.name
    this.tools = config.tools || {}
    this.parentTools = config.parentTools || []
    this.llmConfig = config.llmConfig || null

    // 子Agent配置
    // tools: { toolName: toolFn } 自定义工具（只属于此子Agent）
    // parentTools: ['read_file'] 从父Agent继承的工具名称列表
    this.config = {}

    this._framework = null
    this._agent = null
    this._parentAgent = null
  }

  install(framework) {
    this._framework = framework
    return this
  }

  start(framework) {
    // 创建子Agent（可能需要等待父agent准备好）
    this._createSubAgent()

    // 注册委托工具到主Agent（通过framework获取父agent）
    this._registerDelegateTool()

    return this
  }

  /**
   * 创建子Agent
   */
  _createSubAgent() {
    // 获取父Agent（主Agent）
    const parentAgent = this._getParentAgent()
    if (!parentAgent) {
      // 父agent还没创建，监听事件等其创建
      if (this._framework) {
        this._framework.on('agent:created', (agent) => {
          if (this._framework._mainAgent && agent === this._framework._mainAgent) {
            // 父agent已创建，更新父agent引用
            this._parentAgent = agent
            // 重新尝试创建子agent
            this._doCreateSubAgent(agent)
            // 注册委托工具
            this._registerDelegateTool()
          }
        })
      }
      return
    }

    this._doCreateSubAgent(parentAgent)
  }

  /**
   * 实际执行创建子Agent
   */
  _doCreateSubAgent(parentAgent) {
    // 避免重复创建
    if (this._agent) {
      return
    }

    // 获取从父Agent继承的工具
    const parentTools = this._getParentTools(parentAgent)

    // 确定LLM配置
    const aiPlugin = this._framework.pluginManager.get('ai')
    const llmConfig = this.llmConfig || (aiPlugin ? aiPlugin.getConfig() : {})


    // 创建子Agent，使用完整的 md 文件内容作为系统提示词
    this._agent = this._framework.createSubAgent({
      name: this.name,
      systemPrompt: this._getFullSystemPrompt(),
      model: llmConfig.model,
      provider: llmConfig.provider,
      apiKey: llmConfig.apiKey,
      baseURL: llmConfig.baseURL,
      tools: this.tools||{},  // 自定义工具
      parentTools: parentTools
    })

    // 注册从父Agent继承的工具
    // for (const tool of parentTools) {
    //   this._framework.registerTool(tool)
    // }

    // Register custom tools (only for this subAgent, won't pollute global)
    // tools format: { toolName: toolDef }
    
    this._parentAgent = parentAgent

    // 注册子Agent到父Agent
    parentAgent.registerSubAgent(this.name, this._agent, this.role, this.description)

    // 监听子Agent的chunk事件并转发给父Agent
    this._agent.on('chunk', (chunk) => {
      chunk.fromSubAgent = this.name
      parentAgent.emit('chunk', chunk)
    })
  }

  /**
   * 获取父Agent
   */
  _getParentAgent() {
    // 优先使用外部传入的获取器
    if (this.config._parentAgentGetter) {
      return this.config._parentAgentGetter()
    }

    // 尝试从framework获取主agent
    if (this._framework._mainAgent) {
      return this._framework._mainAgent
    }

    // 查找最后一个创建的agent作为父agent
    const agents = this._framework._agents || []
    if (agents.length > 0) {
      return agents[agents.length - 1]
    }

    return null
  }

  /**
   * 获取从父Agent继承的工具
   */
  _getParentTools(parentAgent) {
    const allTools = parentAgent.getTools ? parentAgent.getTools() : []
    const toolMap = new Map(allTools.map(t => [t.name, t]))

    // 如果没有指定 parentTools，返回全部
    if (!this.parentTools || this.parentTools.length === 0) {
      return allTools
    }
    // 过滤指定工具
    const filtered = []
    for (const toolName of this.parentTools) {
      const tool = toolMap.get(toolName)
      if (tool) {
        filtered.push(tool)
      } 
      // else {
      //   console.warn(`[SubAgent:${this.config.name}] Parent tool not found: ${toolName}`)
      // }
    }

    return filtered
  }

  /**
   * 构建系统提示
   */
  _buildSystemPrompt() {
    return `你是 ${this.role}。

角色描述：${this.description || '一个专业的子Agent'}

当你被调用时，你应该：
1. 仔细理解任务要求
2. 使用你的工具集完成任务
3. 返回完整的操作结果

重要：返回结果要简洁明确，只包含最终结果，不需要解释过程。`
  }

  /**
   * 注册委托工具到框架和主Agent
   */
  _registerDelegateTool() {
    const framework = this._framework
    if (!framework) return

    const agentName = this.name
    const role = this.role

    const toolDef = {
      name: agentName,
      description: `${role}：当需要${role}时，调用此工具执行任务。如：编译代码、运行测试、代码重构等。`,
      inputSchema: z.object({
        task: z.string().describe('给子Agent的具体任务描述')
      }),
      execute: async (args, fw) => {
        if (!this._agent) {
          return { error: `SubAgent ${agentName} not initialized` }
        }

        const parentAgent = fw._mainAgent
        if (!parentAgent) {
          return { error: `Parent agent not found` }
        }

        // 发射子Agent开始处理事件
        parentAgent.emit('subagent:chat:start', {
          parentAgent,
          subAgent: this._agent,
          subAgentName: agentName,
          task: args.task
        })

        try {
          const result = await this._agent.chat(args.task)
          // 发射子Agent完成处理事件
          parentAgent.emit('subagent:chat:end', {
            parentAgent,
            subAgent: this._agent,
            subAgentName: agentName,
            result
          })
          return {
            agent: agentName,
            result: result.message || result.error || result,
            success: result.success !== false
          }
        } catch (err) {
          // 发射子Agent错误事件
          parentAgent.emit('subagent:error', {
            parentAgent,
            subAgent: this._agent,
            subAgentName: agentName,
            error: err.message
          })
          return {
            agent: agentName,
            error: err.message,
            success: false
          }
        }
      }
    }

    // 注册到框架（供后续创建的 Agent 同步）
    // framework.registerTool(toolDef)

    // // 如果主 Agent 已存在，直接注册到它
    // if (framework._mainAgent) {
    //   framework._mainAgent.registerTool(toolDef)
    // }

    //console.log(`[SubAgent:${this.config.name}] Delegate tool registered`)
  }

  /**
   * 获取子Agent实例
   */
  getAgent() {
    return this._agent
  }

  /**
   * 调用子Agent处理任务
   * 延迟创建 Agent，使用完整的 md 文件内容作为系统提示词
   */
  async chat(task) {
    // 延迟创建 Agent（如果尚未创建）
    if (!this._agent) {
      await this._createSubAgentForChat();
    } else {
      // 每次调用时更新系统提示词，确保使用最新的 md 文件内容
      this._updateAgentSystemPrompt();
    }
    return this._agent.chat(task)
  }

  /**
   * 创建用于聊天的高完整度 Agent
   * 使用 SubAgentConfig 读取完整的 md 文件内容
   */
  async _createSubAgentForChat() {
    const parentAgent = this._getParentAgent();
    if (!parentAgent) {
      throw new Error(`SubAgent ${this.name}: parent agent not found`);
    }

    // 使用 SubAgentConfig 获取完整的系统提示词
    const systemPrompt = this._getFullSystemPrompt();
    const parentTools = this._getParentTools(parentAgent)
    // 获取 LLM 配置
    const aiPlugin = this._framework.pluginManager.get('ai');
    const llmConfig = this.llmConfig || (aiPlugin ? aiPlugin.getConfig() : {});

    // 创建 Agent，使用完整的 md 内容作为系统提示词
    this._agent = this._framework.createSubAgent({
      name: this.name,
      systemPrompt: systemPrompt,
      model: llmConfig.model,
      provider: llmConfig.provider,
      apiKey: llmConfig.apiKey,
      baseURL: llmConfig.baseURL,
      tools: this.tools||{},  // 自定义工具
      parentTools: parentTools
    });

    // 注册到父 Agent
    this._parentAgent = parentAgent;
    parentAgent.registerSubAgent(this.name, this._agent, this.role, this.description);
  }

  /**
   * 获取完整的系统提示词（从 md 文件读取）
   */
  _getFullSystemPrompt() {
    // 尝试从 SubAgentConfigManager 获取完整内容
    const configManager = this._framework._subAgentConfigManager;
    if (configManager) {
      const config = configManager.get(this.name); 
      if (config) {
        return config.getSystemPrompt();
      }
    }

    // 回退到默认的 _buildSystemPrompt
    return this._buildSystemPrompt();
  }

  /**
   * 更新 Agent 的系统提示词
   */
  _updateAgentSystemPrompt() {
    if (!this._agent) return;
    const systemPrompt = this._getFullSystemPrompt();
    this._agent.setSystemPrompt(systemPrompt);
  }

  reload(framework) {
    this._framework = framework
    this._createSubAgent()
  }

  uninstall(framework) {
    if (this._parentAgent) {
      this._parentAgent.unregisterSubAgent(this.name)
    }
    if (this._agent) {
      this._agent.destroy()
      this._agent = null
    }
    this._parentAgent = null
    this._framework = null
  }
}

/**
 * SubAgentManager - 管理多个子Agent
 */
class SubAgentManagerPlugin extends Plugin {
  constructor(config = {}) {
    super()
    this.name = 'subagent-manager'
    this.version = '1.0.0'
    this.description = '子Agent管理器，统一管理多个子Agent'

    this.systemPrompt= `你是一个子Agent管理器，负责管理多个子Agent。每个子Agent都有独立的工具集和角色描述。当需要处理特定任务时，你会选择合适的子Agent来执行。`

    this.priority = 10
    this.agents = config.agents || []  // 预定义的子Agent配置列表
    this.config = {
      agentsDir: config.agentsDir || null,  // 子Agent配置目录
    }

    this._framework = null
    this._subAgents = new Map()
    this._fileWatcher = null
    this._lastFileStates = new Map()  // 记录文件状态用于检测变化
  }

  install(framework) {
    this._framework = framework
    return this
  }

  start(framework) {
    // 从 agentsDir 加载子Agent配置
    this._loadAgentsFromDir()

    // 创建所有配置的子Agent
    for (const agentConfig of this.agents) {
      const plugin = new SubAgentPlugin(agentConfig)
      plugin.install(framework)
      plugin.start(framework)
      this._subAgents.set(agentConfig.name, plugin)
    }

    // 注册管理工具
    // 如果主 Agent 已存在，直接注册到它（因为它不会自动同步框架工具）
    if (framework._mainAgent) {
      this._registerToolsToAgent(framework._mainAgent)
    }
    // 同时注册到框架（供后续创建的 Agent 同步）
    this._registerTools(framework)

    // 监听主 Agent 创建事件，为后续创建的主 Agent 注册工具
    framework.on('agent:created', (agent) => {
      if (framework._mainAgent && agent === framework._mainAgent) {
        this._registerToolsToAgent(agent)
      }
    })

    // 启动文件监控
    this._startFileWatcher()

    return this
  }

  /**
   * 注册管理工具到指定 Agent
   */
  _registerToolsToAgent(agent) {
    agent.registerTool({
      name: 'subagent_list',
      description: '列出所有子Agent',
      inputSchema: z.object({}),
      execute: async () => {
        const agents = Array.from(this._subAgents.values()).map(p => ({
          name: p.name,
          role: p.role,
          description: p.description,
          toolCount: p._agent ? p._agent.getTools().length : 0
        }))
        return { success: true, agents }
      }
    })

    agent.registerTool({
      name: 'subagent_call',
      description: '调用指定的子Agent处理任务',
      inputSchema: z.object({
        agentName: z.string().describe('子Agent名称'),
        task: z.string().describe('任务描述')
      }),
      execute: async (args) => {
        const plugin = this._subAgents.get(args.agentName)
        if (!plugin) {
          return { success: false, error: `SubAgent ${args.agentName} not found` }
        }

        try {
          const result = await plugin.chat(args.task)
          return {
            success: true,
            agent: args.agentName,
            result: result.message || result,
            success: result.success !== false
          }
        } catch (err) {
          return { success: false, error: err.message }
        }
      }
    })

    agent.registerTool({
      name: 'subagent_reload',
      description: '重新加载子Agent配置（当新增或删除.agent/agents下的文件后使用）',
      inputSchema: z.object({}),
      execute: async () => {
        try {
          this.reload(this._framework)
          return { success: true, message: '子Agent配置已重新加载' }
        } catch (err) {
          return { success: false, error: err.message }
        }
      }
    })

    //log.info(' Management tools registered to agent')
  }

  /**
   * 注册管理工具到框架工具注册表
   */
  _registerTools(framework) {
    framework.registerTool({
      name: 'subagent_list',
      description: '列出所有子Agent',
      inputSchema: z.object({}),
      execute: async () => {
        const agents = Array.from(this._subAgents.values()).map(p => ({
          name: p.name,
          role: p.role,
          description: p.description,
          toolCount: p._agent ? p._agent.getTools().length : 0
        }))
        return { success: true, agents }
      }
    })

    framework.registerTool({
      name: 'subagent_call',
      description: '调用指定的子Agent处理任务',
      inputSchema: z.object({
        agentName: z.string().describe('子Agent名称'),
        task: z.string().describe('任务描述')
      }),
      execute: async (args) => {
        const plugin = this._subAgents.get(args.agentName)
        if (!plugin) {
          return { success: false, error: `SubAgent ${args.agentName} not found` }
        }

        try {
          const result = await plugin.chat(args.task)
          return {
            success: true,
            agent: args.agentName,
            result: result.message || result,
            success: result.success !== false
          }
        } catch (err) {
          return { success: false, error: err.message }
        }
      }
    })

    framework.registerTool({
      name: 'subagent_reload',
      description: '重新加载子Agent配置（当新增或删除.agent/agents下的文件后使用）',
      inputSchema: z.object({}),
      execute: async () => {
        try {
          this.reload(this._framework)
          return { success: true, message: '子Agent配置已重新加载' }
        } catch (err) {
          return { success: false, error: err.message }
        }
      }
    })

    //log.info(' Management tools registered to framework')
  }

  /**
   * 从 agentsDir 目录加载子Agent配置
   */
  _loadAgentsFromDir() {
    const agentsDir = this.config.agentsDir
    //log.info(' _loadAgentsFromDir called, agentsDir:', agentsDir)
    if (!agentsDir || !fs.existsSync(agentsDir)) {
      log.info(' agentsDir not found or does not exist')
      return
    }

    const entries = fs.readdirSync(agentsDir, { withFileTypes: true })
    //log.info(' Found entries:', entries.length)

    for (const entry of entries) {
      if (entry.isFile() && (entry.name.endsWith('.js') || entry.name.endsWith('.json') || entry.name.endsWith('.md'))) {
        const baseName = entry.name.replace(/\.(js|json|md)$/, '')
        const filePath = path.join(agentsDir, entry.name)

        // 跳过与已有配置同名的
        if (this.agents.some(a => a.name === baseName)) {
          continue
        }

        try {
          let agentConfig
          if (entry.name.endsWith('.json')) {
            const content = fs.readFileSync(filePath, 'utf-8')
            agentConfig = JSON.parse(content)
          } else if (entry.name.endsWith('.md')) {
            // 解析 markdown 文件，提取 JSON 配置
            agentConfig = this._parseMarkdownConfig(filePath, baseName)
            //log.info(' Parsed md:', baseName, agentConfig)
          } else {
            // 清除缓存并加载
            delete require.cache[require.resolve(filePath)]
            const mod = require(filePath)
            agentConfig = typeof mod === 'function' ? mod() : mod
          }

          if (agentConfig && agentConfig.name) {
            agentConfig._fromDir = true
            this.agents.push(agentConfig)
            //log.info(' Loaded agent:', agentConfig.name)
          } else {
            log.warn(' Agent config has no name:', baseName, agentConfig)
          }
        } catch (err) {
          log.warn(` Failed to load agent config from ${filePath}:`, err.message, err.stack)
        }
      }
    }
  }

  /**
   * 解析 markdown 文件中的配置
   * 支持格式：
   * ```json
   * { "name": "xxx", "role": "xxx" }
   * ```
   * 或直接用 frontmatter 格式
   */
  _parseMarkdownConfig(filePath, defaultName) {
    const content = fs.readFileSync(filePath, 'utf-8')
    //log.info(' _parseMarkdownConfig:', filePath)

    // 尝试从 code block 中提取 JSON
    const jsonMatch = content.match(/```(?:json)?\s*\n([\s\S]*?)\n\s*```/)
    if (jsonMatch) {
      try {
        const config = JSON.parse(jsonMatch[1].trim())
        //log.info(' Found JSON in code block')
        return config
      } catch (err) {
        // JSON 解析失败，继续
      }
    }

    // 尝试从 frontmatter 格式中提取
    const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/)
    if (frontmatterMatch) {
      //log.info(' Found frontmatter')
      const frontmatterContent = frontmatterMatch[1]
      const parsed = this._parseYamlLike(frontmatterContent)
      if (parsed && parsed.name) {
        //log.info(' Parsed frontmatter:', parsed)
        return { name: parsed.name || defaultName, ...parsed }
      }
    }

    // 从 markdown 内容中提取配置（key: value 格式）
    const config = { name: defaultName }
    const yamlMatch = content.match(/^(name|role|description|parentTools|tools):\s*(.+)$/m)
    if (yamlMatch) {
      config[yamlMatch[1]] = yamlMatch[2].trim()
    }

    // 如果没有找到配置，使用文件名作为 name
    return config
  }

   /**
   * 获取所有 subAgent 的基本信息列表
   */
  getAllSubAgents() {
    return Array.from(this._subAgents.values());
  }

  /**
   * 解析类似 YAML 的配置
   */
  _parseYamlLike(content) {
    const result = {}
    const lines = content.split('\n')

    for (const line of lines) {
      const match = line.match(/^(\w+):\s*(.+)$/)
      if (match) {
        const key = match[1]
        let value = match[2].trim()

        // 处理数组格式 [a, b, c] 或 [a b c]
        if (value.startsWith('[') && value.endsWith(']')) {
          value = value.slice(1, -1).split(/[,\s]+/).filter(Boolean)
        }

        result[key] = value
      }
    }

    return result
  }

  /**
   * 启动文件监控
   */
  _startFileWatcher() {
    const agentsDir = this.config.agentsDir
    if (!agentsDir || !fs.existsSync(agentsDir)) {
      return
    }

    // 记录初始文件状态
    this._updateFileStates()

    // 使用 fs.watch 监控目录变化
    this._fileWatcher = fs.watch(agentsDir, { recursive: false }, (eventType, filename) => {
      if (filename && (filename.endsWith('.js') || filename.endsWith('.json') || filename.endsWith('.md'))) {
        //console.log(`[SubAgentManager] Detected change in agents dir: ${eventType} - ${filename}`)

        // 防抖：延迟处理，等文件操作完成
        setTimeout(() => {
          this._checkAndReload()
        }, 500)
      }
    })

    //console.log(`[SubAgentManager] Watching agents dir for changes: ${agentsDir}`)
  }

  /**
   * 更新文件状态
   */
  _updateFileStates() {
    const agentsDir = this.config.agentsDir
    if (!agentsDir || !fs.existsSync(agentsDir)) {
      return
    }

    this._lastFileStates.clear()
    const entries = fs.readdirSync(agentsDir, { withFileTypes: true })

    for (const entry of entries) {
      if (entry.isFile() && (entry.name.endsWith('.js') || entry.name.endsWith('.json') || entry.name.endsWith('.md'))) {
        const filePath = path.join(agentsDir, entry.name)
        try {
          const stat = fs.statSync(filePath)
          this._lastFileStates.set(entry.name, {
            mtime: stat.mtime.getTime(),
            size: stat.size
          })
        } catch (err) {
          // 忽略
        }
      }
    }
  }

  /**
   * 检查并重载（如果有变化）
   */
  _checkAndReload() {
    const agentsDir = this.config.agentsDir
    if (!agentsDir || !fs.existsSync(agentsDir)) {
      return
    }

    const currentStates = new Map()
    const entries = fs.readdirSync(agentsDir, { withFileTypes: true })
    let hasChanges = false

    // 检查当前文件
    for (const entry of entries) {
      if (entry.isFile() && (entry.name.endsWith('.js') || entry.name.endsWith('.json') || entry.name.endsWith('.md'))) {
        const filePath = path.join(agentsDir, entry.name)
        try {
          const stat = fs.statSync(filePath)
          currentStates.set(entry.name, {
            mtime: stat.mtime.getTime(),
            size: stat.size
          })

          const lastState = this._lastFileStates.get(entry.name)
          if (!lastState || lastState.mtime !== stat.mtime.getTime() || lastState.size !== stat.size) {
            hasChanges = true
          }
        } catch (err) {
          // 忽略
        }
      }
    }

    // 检查删除的文件
    for (const [name] of this._lastFileStates) {
      if (!currentStates.has(name)) {
        hasChanges = true
        break
      }
    }

    if (hasChanges) {
      //log.info(' File changes detected, reloading...')
      this._updateFileStates()
      this.reload(this._framework)
    }
  }

  /**
   * 获取子Agent
   */
  getSubAgent(name) {
    const plugin = this._subAgents.get(name)
    return plugin ? plugin.getAgent() : null
  }

  reload(framework) {
    // 停止文件监控
    if (this._fileWatcher) {
      this._fileWatcher.close()
      this._fileWatcher = null
    }

    // 销毁旧的子Agent
    for (const plugin of this._subAgents.values()) {
      plugin.uninstall(framework)
    }
    this._subAgents.clear()

    // 清空从目录加载的配置，重新加载
    this.agents = this.agents.filter(a => !a._fromDir)

    // 刷新 SubAgentConfigManager（如果存在）
    if (framework._subAgentConfigManager) {
      framework._subAgentConfigManager.refresh()
    }

    // 重新创建
    this.start(framework)
  }

  uninstall(framework) {
    // 停止文件监控
    if (this._fileWatcher) {
      this._fileWatcher.close()
      this._fileWatcher = null
    }

    for (const plugin of this._subAgents.values()) {
      plugin.uninstall(framework)
    }
    this._subAgents.clear()
    this._framework = null
  }
}

module.exports = {
  SubAgentManagerPlugin,
  SubAgentPlugin
}