/**
 * Plugin 基类
 * 所有插件的基类
 */

class Plugin {
  /**
   * 插件名称
   * @type {string}
   */
  name = 'unnamed-plugin';

  /**
   * 插件版本
   * @type {string}
   */
  version = '1.0.0';

  /**
   * 插件描述
   * @type {string}
   */
  description = '';

  /**
   * 插件优先级，数值越小越先加载
   * @type {number}
   */
  priority = 100;

  /**
   * 子Agent配置数组 - 配置后自动注册子Agent
   * 格式: [{ name: 'xxx', role: '角色', tools: {...}, parentTools: [...] }]
   * @type {Array}
   */
  agents = [];

  /**
   * 插件是否启用，默认为 true
   * 设置为 false 时插件不会被加载，但在列表中仍可见
   * @type {boolean}
   */
  enabled = true;

  /**
   * 是否为系统插件，默认为 false
   * 系统插件不能被禁用，始终启用
   * @type {boolean}
   */
  system = false;

  _framework = null;
  _subAgents = [];

  /**
   * 插件注册的工具集（供 ExtensionExecutor 自动加载）
   * 格式: { toolName: { name, description, inputSchema, execute } }
   * @type {Object}
   */
  tools = {};

  /**
   * 安装插件 - 注册工具/事件等
   * @param {Framework} framework - 框架实例
   */
  install(framework) {
    this._framework = framework;
    return this;
  }

  /**
   * 注册工具到扩展执行器（供 ExtensionExecutor 统一管理）
   * 支持三种调用方式：
   *   this.registerTool('name', { description, inputSchema, execute })
   *   this.registerTool({ name, description, inputSchema, execute })
   *   this.registerTool({ name, description, inputSchema, execute, pluginName: 'xxx' })
   * @param {string|Object} name - 工具名称或工具定义对象
   * @param {Object} [def] - 工具定义 { description, inputSchema, execute }
   */
  registerTool(name, def) {
    if (!this._framework) return;
    // 支持 this.registerTool({ name, description, ... }) 形式
    if (typeof name === 'object' && name !== null) {
      def = name;
      name = def.name;
    }
    if (!name || !def) return;

    // 支持自定义插件名
    const pluginName = def.pluginName || this.name;
    delete def.pluginName;

    const extExec = this._framework.pluginManager.get('extension-executor');
    if (extExec) {
      extExec.registerTool(
        pluginName,
        {
          name: pluginName,
          description: def.description || this.description,
          version: this.version,
        },
        { name, ...def }
      );
    }
  }

  /**
   * 启动插件 - 初始化完成后的启动
   * @param {Framework} framework - 框架实例
   */
  start(framework) {
    // 自动注册配置的子Agent
    this._autoRegisterSubAgents();
    return this;
  }

  /**
   * 自动注册子Agent（根据 this.agents 配置）
   * @private
   */
  _autoRegisterSubAgents() {
    // 确定要注册的agent配置
    const agentsToRegister = this._deferredSubAgents || this.agents;
    if (!agentsToRegister || !Array.isArray(agentsToRegister) || agentsToRegister.length === 0) {
      return;
    }

    // 获取父Agent
    const parentAgent = this._getParentAgent();

    if (!parentAgent) {
      // 没有父Agent，推迟到框架准备好时再注册
      if (!this._deferredSubAgents) {
        log.debug(` No parent agent found, deferring subagent registration`);
        this._deferredSubAgents = agentsToRegister;
        // 监听框架准备好事件
        if (this._framework) {
          this._framework.once('framework:ready', () => {
            // 延迟注册，确保主Agent已创建
            setTimeout(() => this._autoRegisterSubAgents(), 100);
          });
        }
      }
      return;
    }

    // 有父Agent了，清除延迟标记
    this._deferredSubAgents = null;

    for (const agentConfig of agentsToRegister) {
      try {
        const plugin = this.registerSubAgent(agentConfig);
        this._subAgents.push(plugin);
      } catch (err) {
        log.error(` Failed to register subagent ${agentConfig.name}:`, err.message);
      }
    }
  }

  /**
   * 获取父Agent
   * @private
   */
  _getParentAgent() {
    if (!this._framework) return null;
    if (this._framework._mainAgent) return this._framework._mainAgent;
    const agents = this._framework._agents || [];
    return agents.length > 0 ? agents[agents.length - 1] : null;
  }

  /**
   * 注册子Agent
   * @param {Object} config - 子Agent配置
   * @param {string} config.name - 子Agent名称
   * @param {string} config.role - 子Agent角色
   * @param {string} [config.description] - 子Agent描述
   * @param {Object} [config.tools] - 自定义工具 { name: toolDef }
   * @param {string[]} [config.parentTools] - 从父Agent继承的工具名称
   * @returns {Object} 注册的子Agent信息
   */
  registerSubAgent(config) {
    if (!this._framework) {
      throw new Error('Plugin not installed, call install(framework) first');
    }

    // 获取 subagent-manager 插件
    const subAgentManager = this._framework.pluginManager.get('subagent-manager');

    if (!subAgentManager) {
      throw new Error('subagent-manager plugin not found');
    }

    // 创建子Agent实例
    const agent = this._framework.createSubAgent({
      name: config.name,
      role: config.role,
      goal: config.description || config.role,
      tools: config.tools || {},
      parentTools: config.parentTools || [],
    });

    // 注册到 subagent-manager
    subAgentManager.registerPlugin({
      name: config.name,
      role: config.role,
      goal: config.description || config.role,
      agent,
      tools: config.tools || {},
    });

    // 保存引用以便后续清理
    this._subAgents.push({
      name: config.name,
      agent,
      plugin: null, // 兼容旧代码
    });

    log.debug(` Registered subagent: ${config.name}`);
    return { name: config.name, agent };
  }

  /**
   * 热重载插件 - 手动调用重载时执行
   * @param {Framework} framework - 框架实例
   */
  reload(framework) {
    this._framework = framework;
    // 清除之前的延迟注册
    this._deferredSubAgents = null;
    // 重新注册子Agent
    this._autoRegisterSubAgents();
  }

  /**
   * 卸载插件 - 清理资源
   * @param {Framework} framework - 框架实例
   */
  uninstall(framework) {
    // 销毁所有子Agent
    for (const plugin of this._subAgents) {
      try {
        plugin.uninstall(framework);
      } catch (err) {
        log.error(` Failed to uninstall subagent:`, err.message);
      }
    }
    this._subAgents = [];
    this._framework = null;
  }

  /**
   * 获取插件信息
   * @returns {Object}
   */
  getInfo() {
    return {
      name: this.name,
      version: this.version,
      description: this.description,
      priority: this.priority,
    };
  }
}

/**
 * 内置插件类型常量
 */
const PluginType = {
  AI: 'ai',
  TOOLS: 'tools',
  EXECUTOR: 'executor',
  CAPABILITY: 'capability',
};

module.exports = { Plugin, PluginType };
