/**
 * 默认插件配置加载器
 * 检测 .agent/ 目录下的配置，提供给 bootstrap() 使用
 */

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('AgentConfig')
const bootstrapLog = logger.child('Bootstrap')

/**
 * 加载 .agent 目录下的配置
 * 返回配置对象，可用于手动加载插件
 */
function loadAgentConfig(agentDir = '.agent') {
  const config = {
    agentDir,
    ai: {},
    mcpServers: {},
    plugins: [],
    skillsDirs: [],
    agentsDir: null    // 子Agent配置目录
  }
  const cmdDir=path.resolve(process.cwd())
  const resolvedDir = path.resolve(process.cwd(), agentDir)

  if (!fs.existsSync(resolvedDir)) {
    log.info(` .agent directory not found: ${resolvedDir}`)
    return config
  }

  log.info(` Loading config from: ${resolvedDir}`)

  // 添加 agents 目录（如果存在）
  const agentsDir = path.join(resolvedDir, 'agents')
  if (fs.existsSync(agentsDir)) {
    config.agentsDir = agentsDir
    log.info(` Found agents directory: ${agentsDir}`)
  }

  // 加载 config 文件（key=value 格式）
  const configFile = path.join(resolvedDir, 'config')
  if (fs.existsSync(configFile)) {
    try {
      const lines = fs.readFileSync(configFile, 'utf-8').split('\n')
      for (const line of lines) {
        const trimmed = line.trim()
        if (!trimmed || trimmed.startsWith('#')) continue

        const colonIndex = trimmed.indexOf(':')
        if (colonIndex === -1) continue

        const key = trimmed.substring(0, colonIndex).trim()
        const value = trimmed.substring(colonIndex + 1).trim()

        if (key === 'ai_key' || key === 'api_key') {
          config.ai.apiKey = value
        } else if (key === 'ai_model' || key === 'model') {
          config.ai.model = value
        } else if (key === 'ai_provider' || key === 'provider') {
          config.ai.provider = value
        } else if (key === 'ai_base_url' || key === 'baseURL') {
          config.ai.baseURL = value
        }
      }
    } catch (err) {
      log.error(` Failed to load config:`, err.message)
    }
  }

  // 加载 ai.json
  const aiFile = path.join(resolvedDir, 'ai.json')
  if (fs.existsSync(aiFile)) {
    try {
      const content = fs.readFileSync(aiFile, 'utf-8')
      const aiConfig = JSON.parse(content)
      config.ai = { ...config.ai, ...aiConfig }
    } catch (err) {
      log.error(` Failed to load ai.json:`, err.message)
    }
  }

  // 加载 plugins.json (支持 telegram, weixin, email 等插件配置)
  const pluginsFile = path.join(resolvedDir, 'plugins.json')
  if (fs.existsSync(pluginsFile)) {
    try {
      const content = fs.readFileSync(pluginsFile, 'utf-8')
      const pluginsConfig = JSON.parse(content)
      // telegram 配置
      if (pluginsConfig.telegram) {
        config.telegram = pluginsConfig.telegram
      }
      // weixin 配置
      if (pluginsConfig.weixin) {
        config.weixin = pluginsConfig.weixin
      }
      // email 配置
      if (pluginsConfig.email) {
        config.email = pluginsConfig.email
      }
    } catch (err) {
      log.error(` Failed to load plugins.json:`, err.message)
    }
  }

  // 加载 weixin.json (如果存在)
  const weixinFile = path.join(resolvedDir, 'weixin.json')
  if (fs.existsSync(weixinFile)) {
    try {
      const content = fs.readFileSync(weixinFile, 'utf-8')
      config.weixin = { ...config.weixin, ...JSON.parse(content) }
    } catch (err) {
      log.error(` Failed to load weixin.json:`, err.message)
    }
  }

  // 加载 mcp_config.json
  const mcpFile = path.join(resolvedDir, 'mcp_config.json')
  if (fs.existsSync(mcpFile)) {
    try {
      const content = fs.readFileSync(mcpFile, 'utf-8')
      const mcpConfig = JSON.parse(content)
      config.mcpServers = mcpConfig.mcpServers || {}
    } catch (err) {
      log.error(` Failed to load mcp_config.json:`, err.message)
    }
  }

  // 添加 .agent/skills 目录（不存在则创建）
  const skillsDir = path.join(resolvedDir, 'skills')
  if (fs.existsSync(resolvedDir) && !fs.existsSync(skillsDir)) {
    fs.mkdirSync(skillsDir, { recursive: true })
    log.info(` Created skills directory: ${skillsDir}`)
  }
  if (fs.existsSync(skillsDir)) {
    config.skillsDirs.push(skillsDir)
  }

  // 添加 .agent/skills 目录（不存在则创建）
  const cmdskillsDir = path.join(cmdDir, 'skills')
  if (fs.existsSync(resolvedDir) && !fs.existsSync(cmdskillsDir)) {
    fs.mkdirSync(cmdskillsDir, { recursive: true })
    log.info(` Created skills directory: ${cmdskillsDir}`)
  }
  if (fs.existsSync(cmdskillsDir)) {
    config.skillsDirs.push(cmdskillsDir)
  }

  // 添加 agentDir 父目录的 skills/ 目录
  const parentDir = path.dirname(__dirname)
  const rootSkillsDir = path.join(parentDir, 'skills')
  if (fs.existsSync(rootSkillsDir)) {
    config.skillsDirs.push(rootSkillsDir)
  }

  // const defaultSkillsDir = path.join(process.cwd(), 'defaultSkills')
  // if (fs.existsSync(defaultSkillsDir)) {
  //   config.skillsDirs.push(defaultSkillsDir)
  // }

  return config
}

/**
 * DefaultPlugins - 默认插件配置加载器
 */
class DefaultPlugins extends Plugin {
  constructor(config = {}) {
    super()
    this.name = 'defaults'
    this.version = '1.0.0'
    this.description = '默认插件配置加载器'
    this.priority = 0  // 最先加载
    this.system = true 

    this._framework = null
    this._agentDir = config.agentDir || '.agent'
    this._config = null
  }

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

  start(framework) {
    // 加载配置
    this._config = loadAgentConfig(this._agentDir)
    return this
  }

  /**
   * 获取加载的配置
   */
  getConfig() {
    return this._config || loadAgentConfig(this._agentDir)
  }

  reload(framework) {
    this._framework = framework
    this._config = loadAgentConfig(this._agentDir)
  }

  uninstall(framework) {
    this._framework = null
    this._config = null
  }
}

/**
 * Bootstrap 辅助函数
 * 根据配置加载所有默认插件
 */
async function bootstrapDefaults(framework, config = {}) {
  // 如果已经有配置，使用现有配置；否则加载
  const agentConfig = config._config
  if (!agentConfig) {
    bootstrapLog.error(' No config provided, skipping plugin loading')
    return
  }
  // 设置 bootstrap 模式，避免重复启动
  framework.pluginManager.setBootstrapping(true)

  // 合并 AI 配置
  const aiConfig = { ...agentConfig.ai, ...config.aiConfig }

  // 核心插件列表（不能禁用，必须加载）
  const CORE_PLUGINS = new Set([
    'install', 'ai', 'storage', 'tools', 'workflow', 'skill-manager',
    'mcp-executor', 'extension-executor', 'shell-executor', 'python-executor', 'session', 'web',
    'audit', 'rules', 'scheduler', 'file-system', 'think', 'ambient',
    'python-plugin-loader', 'telegram', 'weixin', 'subagent-manager',
    'memory', 'coordinator'
  ])

  // 辅助函数：检查插件是否应该加载
  // 传入插件名称（字符串）、已创建的实例，或插件类
  const shouldLoad = (plugin) => {
    const name = typeof plugin === 'string' ? plugin : (plugin.name || plugin.prototype?.name)
    if (framework.pluginManager.has(name)) {
      framework._debug&&bootstrapLog.debug(` ${name} Plugin already loaded, skipping`)
      return false
    }
    // 系统插件（system: true）不能禁用
    let isSystem = false
    if (typeof plugin === 'function') {
      isSystem = plugin.prototype?.system === true
    } else if (typeof plugin === 'object') {
      isSystem = plugin.system === true
    }
    if (isSystem && framework.pluginManager.isEnabled(name) === false) {
      framework._debug&&bootstrapLog.debug(` ${name} is a system plugin, cannot be disabled`)
    }
    return true
  }

  // 0. Install 工具插件（最先加载，让其他插件能用到它的 node_modules）
  if (shouldLoad('install')) {
    const InstallPlugin = require('./install-plugin')
    await framework.loadPlugin(new InstallPlugin({ agentDir: agentConfig.agentDir }))
    framework._debug&&bootstrapLog.debug(' Install Plugin loaded')
  }

  // 合并 skillsDirs 配置（bootstrap 传入的优先）
  const skillsDirs = [
    ...(config.skillsDirs || []),
    ...(agentConfig.skillsDirs || [])
  ]

  framework._debug&&bootstrapLog.debug(' Loading default plugins...')
  // AI 插件（如果已禁用则跳过）
  if (!shouldLoad('ai') || !(aiConfig.provider || aiConfig.model || aiConfig.apiKey)) {
    // 跳过或已禁用
  } else {
    const AIPlugin = require('./ai-plugin')
    // 根据 provider 获取对应的 API key
    const upperProvider = (aiConfig.provider || 'deepseek').toUpperCase().replace(/-/g, '_')
    const envApiKey = process.env[`${upperProvider}_API_KEY`] || process.env.FOLIKO_API_KEY
    const aiPlugin = new AIPlugin({
      provider: aiConfig.provider || 'deepseek',
      model: aiConfig.model || 'deepseek-chat',
      apiKey: aiConfig.apiKey || envApiKey,
      baseURL: aiConfig.baseURL
    })
    await framework.loadPlugin(aiPlugin)
    framework._debug&&bootstrapLog.debug(' AI Plugin loaded')
  }

  // 1.5 创建主 Agent（供 Telegram 等需要绑定 Agent 的插件使用）
  // 注意：即使没有 AI 配置也创建主 agent，让 memory-plugin 等能注册 prompt parts
  if (!framework._mainAgent) {
    const { Agent } = require('../src/core/agent')
    const aiPlugin = framework.pluginManager.get('ai')
    const aiClient = aiPlugin ? aiPlugin.getAIClient() : null
    framework._debug&&bootstrapLog.debug(' Creating Main Agent - aiClient:', !!aiClient)

    framework._mainAgent = framework.createAgent({
      name: 'MainAgent',
      systemPrompt: '你是一个智能助手。当用户提出问题或任务时，你会主动分析需求，选择合适的工具来获取信息或执行操作。你善于将复杂任务拆解为多个步骤，通过工具协作完成。',
      model: aiConfig.model || 'deepseek-chat',
      provider: aiConfig.provider || 'deepseek',
      apiKey: aiConfig.apiKey,
      baseURL: aiConfig.baseURL
    })
    framework._agents.push(framework._mainAgent)
    framework._debug&&bootstrapLog.debug(' Main Agent created, has _chatHandler:', !!framework._mainAgent._chatHandler)
  }

  // 2. Skill 管理器插件（需要 skillsDirs 配置）
  if (shouldLoad('skill-manager') && skillsDirs.length > 0) {
    const { SkillManagerPlugin } = require('../src/capabilities/skill-manager')
    await framework.loadPlugin(new SkillManagerPlugin({ skillsDirs }))
    framework._debug&&bootstrapLog.debug(' Skill Manager loaded')
  }

  // 3. MCP 执行器插件（需要转换 mcpServers 格式）
  if (shouldLoad('mcp-executor')) {
    const mcpServers = Object.entries(agentConfig.mcpServers || {})
    const servers = mcpServers.map(([name, cfg]) => ({
      ...cfg,
      name,
      command: cfg.command,
      args: cfg.args || [],
      env: cfg.env || {},
      url: cfg.url,
      headers: cfg.headers
    }))
    const { MCPExecutorPlugin } = require('../src/executors/mcp-executor')
    await framework.loadPlugin(new MCPExecutorPlugin({ servers }))
    framework._debug&&bootstrapLog.debug(` MCP Executor loaded${servers.length > 0 ? ` (${servers.length} servers)` : ' (no servers)'}`)
  }

  // 4. Python 插件加载器（需要 agentDir）
  if (shouldLoad('python-plugin-loader')) {
    const PythonPluginLoader = require('./python-plugin-loader')
    await framework.loadPlugin(new PythonPluginLoader({ agentDir: agentConfig.agentDir }))
    framework._debug&&bootstrapLog.debug(' Python Plugin Loader loaded')
  }

  // 5. SubAgent 管理器（需要特殊初始化 SubAgentConfigManager）
  if (shouldLoad('subagent-manager')) {
    try {
      const { SubAgentConfigManager } = require('../src/core/sub-agent-config')
      const subAgentConfigManager = new SubAgentConfigManager(agentConfig.agentsDir)
      subAgentConfigManager.loadAll()
      framework._subAgentConfigManager = subAgentConfigManager

      const { SubAgentManagerPlugin } = require('./subagent-plugin')
      await framework.loadPlugin(new SubAgentManagerPlugin({ agentsDir: agentConfig.agentsDir }))
      framework._debug&&bootstrapLog.debug(' SubAgent Manager loaded')
    } catch (err) {
      bootstrapLog.warn(' SubAgent Manager failed:', err.message)
    }
  }

  // 6. 自动加载 plugins/ 目录下的所有插件
  await loadCustomPlugins(framework, agentConfig)

  framework._debug&&bootstrapLog.debug(' All plugins loaded')

  // 统一启动所有插件（避免重复启动）
  await framework.pluginManager.startAll()

  // 清除 bootstrap 模式
  framework.pluginManager.setBootstrapping(false)

  framework._debug&&bootstrapLog.debug(' Loaded plugins ', framework.pluginManager.getAll().length)
  framework._debug&&bootstrapLog.debug(' Loaded tools ', framework.getTools().length)
}

/**
 * 解析插件路径
 * 支持两种结构：
 * 1. 文件夹结构: .agent/plugins/my-plugin/index.js
 * 2. 单文件结构: .agent/plugins/my-plugin.js
 * @param {string} pluginsDir - 插件目录
 * @param {string} name - 插件名称
 * @returns {{path: string, type: 'folder'|'file'}|null} 插件路径和类型
 */
function resolvePluginPath(pluginsDir, name) {
  const folderPath = path.join(pluginsDir, name)
  const filePath = path.join(pluginsDir, `${name}.js`)

  // 文件夹优先
  if (fs.existsSync(folderPath) && fs.statSync(folderPath).isDirectory()) {
    const pkgPath = path.join(folderPath, 'package.json')
    if (fs.existsSync(pkgPath)) {
      try {
        const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))
        const main = pkg.main || 'index.js'
        const mainPath = path.join(folderPath, main)
        if (fs.existsSync(mainPath)) {
          return { path: mainPath, type: 'folder' }
        }
      } catch (err) {
        log.warn(` Failed to parse package.json for ${name}:`, err.message)
      }
    }
    // 默认加载 index.js
    const indexPath = path.join(folderPath, 'index.js')
    if (fs.existsSync(indexPath)) {
      return { path: indexPath, type: 'folder' }
    }
    //log.warn(` No entry point found for plugin folder: ${name}`)
    return null
  }

  // 单文件回退
  if (fs.existsSync(filePath)) {
    return { path: filePath, type: 'file' }
  }

  return null
}

/**
 * 扫描插件目录，返回所有插件名称
 * @param {string} pluginsDir - 插件目录
 * @returns {string[]} 插件名称列表
 */
function scanPluginNames(pluginsDir) {
  if (!fs.existsSync(pluginsDir)) {
    return []
  }

  const names = new Set()
  const entries = fs.readdirSync(pluginsDir, { withFileTypes: true })

  for (const entry of entries) {
    if (entry.isDirectory()) {
      // 文件夹插件
      names.add(entry.name)
    } else if (entry.isFile() && entry.name.endsWith('.js')) {
      // 单文件插件（排除与文件夹同名的）
      const baseName = entry.name.replace(/\.js$/, '')
      if (!names.has(baseName)) {
        names.add(baseName)
      }
    }
  }

  return Array.from(names)
}

async function loadCustomPlugins(framework, agentConfig) {
  const { Plugin } = require('../src/core/plugin-base')

  // 加载两个目录下的自定义插件：
  // 1. .agent/plugins/ - 用户自定义插件（强制启用）
  // 2. plugins/ - 项目内置插件（自动加载）
  const dirs = [
    { dir: path.resolve(process.cwd(), '.agent', 'plugins'), forceEnabled: true },
    { dir: path.resolve(process.cwd(), 'plugins'), forceEnabled: false },
    { dir: path.resolve(__dirname, '..', 'plugins'), forceEnabled: false }   
    // 项目下的 plugins 目录（兼容旧版本）
    
  ]

  for (const { dir, forceEnabled } of dirs) {
    if (!fs.existsSync(dir)) {
      continue
    }

    // 扫描所有插件名称（支持文件夹和单文件）
    const pluginNames = scanPluginNames(dir)

    for (const pluginName of pluginNames) {
      try {
        const resolved = resolvePluginPath(dir, pluginName)
        if (!resolved) {
          continue
        }

        const { path: pluginPath, type } = resolved

        // 清除缓存
        delete require.cache[require.resolve(pluginPath)]
        const pluginModule = require(pluginPath)

        let plugin
        if (typeof pluginModule === 'function') {
          plugin = pluginModule
        } else if (pluginModule.default) {
          plugin = pluginModule.default
        } else {
          // 支持具名导出 { PluginClass } 或 { PluginClass, Other }
          // 找到第一个是 Plugin 子类的导出
          const keys = Object.keys(pluginModule)
          let foundPlugin = null
          for (const key of keys) {
            const exp = pluginModule[key]
            if (typeof exp === 'function' && exp.prototype instanceof Plugin) {
              foundPlugin = exp
              break
            }
          }
          plugin = foundPlugin || pluginModule
        }

        // 获取插件名称（参考 plugin-manager 的逻辑）
        let resolvedPluginName = pluginName
        if (typeof plugin === 'function' && plugin.prototype instanceof Plugin) {
          // Plugin 子类：实例化获取名称
          const instance = new plugin()
          resolvedPluginName = instance.name || pluginName
        } else if (typeof plugin === 'function') {
          // 工厂函数
          const result = plugin(Plugin)
          resolvedPluginName = result?.name || pluginName
        } else {
          resolvedPluginName = plugin?.name || pluginName
        }

        // 如果插件已加载且已启动，跳过
        if (framework.pluginManager.has(resolvedPluginName) &&
            framework.pluginManager.get(resolvedPluginName)?._started) {
          continue
        }

        bootstrapLog.debug(` Loading plugin: ${resolvedPluginName} (${type})`)

        // 从 agentConfig 获取插件配置
        const pluginConfig = agentConfig[resolvedPluginName] || {}

        // 实例化插件并传入配置
        let pluginInstance
        if (typeof plugin === 'function' && plugin.prototype instanceof Plugin) {
          pluginInstance = new plugin(pluginConfig)
        } else {
          pluginInstance = plugin
        }

        await framework.pluginManager.load(pluginInstance, { forceEnabled })
      } catch (err) {
        log.error(` Failed to load plugin ${pluginName}:`, err.message)
      }
    }
  }
}

module.exports = {
  DefaultPlugins,
  loadAgentConfig,
  bootstrapDefaults,
  loadCustomPlugins,
  resolvePluginPath,
  scanPluginNames
}
