/**
 * Framework 核心容器
 * 管理所有子系统，提供统一入口
 */

const path = require('path');
const { AsyncLocalStorage } = require('async_hooks');
const { EventEmitter } = require('../utils/event-emitter');
const { PluginManager } = require('./plugin-manager');
const { ToolRegistry } = require('./tool-registry');
const { Agent } = require('./agent');
const { SubAgentConfigManager } = require('./sub-agent-config');
const { ContextManager } = require('./context-manager');
const { SessionContext } = require('./session-context');
const { SessionStorageAdapter, getDefaultAdapter } = require('./session-storage');
const { CoordinatorManager } = require('./coordinator-manager');

// 添加框架目录的 node_modules 到全局搜索路径
// 让项目插件能 require 框架内置的包（如 zod）
const frameworkNodeModules = path.join(__dirname, '..', '..', 'node_modules');
if (!module.paths.includes(frameworkNodeModules)) {
  module.paths.unshift(frameworkNodeModules);
}

// 现有的 AsyncLocalStorage（保持向后兼容）
const asyncLocalStorage = new AsyncLocalStorage();

// 新增：三层 AsyncLocalStorage
const requestStorage = new AsyncLocalStorage(); // Request 级别
const sessionStorage = new AsyncLocalStorage(); // Session 级别
const agentStorage = new AsyncLocalStorage(); // Agent 级别

class Framework extends EventEmitter {
  /**
   * @param {Object} config - 配置
   * @param {boolean} [config.debug=false] - 调试模式
   */
  constructor(config = {}) {
    super();

    this._debug = config.debug || false;
    this._ready = false;
    this._readyPromise = null;
    this._resolveReady = null;

    // 初始化子系统
    this.toolRegistry = new ToolRegistry();
    this.pluginManager = new PluginManager(this);

    // Agent 管理
    this._agents = []; // 所有创建的 agent
    this._mainAgent = null; // 主 agent

    // 子代理配置管理器
    this._subAgentConfigManager = null;

    // 执行上下文（工具调用时可用）
    this._executionContext = null;

    // ========== 分层上下文系统 ==========
    // Context 管理器
    this._contextManager = new ContextManager(this);

    // SessionContext 缓存（轻量管理，不依赖 ContextManager）
    this._sessionContexts = new Map(); // sessionId → SessionContext

    // Session 存储适配器（默认使用文件存储）
    this._sessionStorage = null;
    this._sessionStorageConfig = config.sessionStorage || {
      type: 'file',
      baseDir: '.agent/sessions',
    };

    // Coordinator管理器（用于Coordinator模式）
    this._coordinatorManager = null;

    // 事件转发 - ToolRegistry 事件
    this.toolRegistry.on('tool:registered', (tool) => {
      this.emit('tool:registered', tool);
    });

    this.toolRegistry.on('tool:call', (data) => {
      this.emit('tool:call', data);
      // 兼容连字符格式
      this.emit('tool-call', data);
    });

    this.toolRegistry.on('tool:result', (data) => {
      this.emit('tool:result', data);
    });

    this.toolRegistry.on('tool:error', (data) => {
      this.emit('tool:error', data);
    });

    // 事件转发 - Agent 事件
    this._setupAgentEventForwarding();

    this._registerBuiltinTools();
  }

  /**
   * 设置 Agent 事件转发
   * @private
   */
  _setupAgentEventForwarding() {
    // 监听 agent:created 事件，为新创建的 Agent 设置事件转发
    this.on('agent:created', (agent) => {
      // 转发 Agent 的 tool-call/result/error 事件
      agent.on('tool-call', (data) => {
        this.emit('tool:call', data);
      });
      agent.on('tool-result', (data) => {
        this.emit('tool:result', data);
      });
      agent.on('tool-error', (data) => {
        this.emit('tool:error', data);
      });
      // 转发 Agent 的 message 事件作为 agent:message
      agent.on('message', (msg) => {
        this.emit('agent:message', msg);
      });
    });
  }

  /**
   * 从 AI 插件合并配置到目标配置对象
   * @param {Object} target - 目标配置对象
   * @private
   */
  _mergeAIConfig(target) {
    if (target.apiKey) return target; // 已有 apiKey 不需要合并

    const aiPlugin = this.pluginManager.get('ai');
    if (!aiPlugin) return target;

    const defaults = {
      apiKey: aiPlugin.config.apiKey,
      provider: aiPlugin.config.provider,
      model: aiPlugin.config.model,
      baseURL: aiPlugin.config.baseURL,
      providerOptions: aiPlugin.config.providerOptions || {},
    };

    return {
      ...target,
      apiKey: target.apiKey || defaults.apiKey,
      provider: target.provider || defaults.provider,
      model: target.model || defaults.model,
      baseURL: target.baseURL || defaults.baseURL,
      providerOptions: target.providerOptions || defaults.providerOptions,
    };
  }

  /**
   * 注册插件（不加载）
   * @param {Plugin|Object} plugin - 插件
   */
  registerPlugin(plugin) {
    this.pluginManager.register(plugin);
    return this;
  }

  /**
   * 加载并启动插件）
   * @param {Plugin|Object} plugin - 插件
   */
  async loadPlugin(plugin) {
    await this.pluginManager.load(plugin);
    return this;
  }

  /**
   * 卸载插件
   * @param {string} name - 插件名称
   */
  async unloadPlugin(name) {
    await this.pluginManager.unload(name);
    return this;
  }

  /**
   * 重载单个插件
   * @param {string} name - 插件名称
   */
  async reloadPlugin(name) {
    await this.pluginManager.reload(name);
    return this;
  }

  /**
   * 重载所有插件）
   */
  async reloadAllPlugins() {
    await this.pluginManager.reloadAll();
    return this;
  }

  /**
   * 启用插件
   * @param {string} name - 插件名称
   */
  async enablePlugin(name) {
    await this.pluginManager.enable(name);
    return this;
  }

  /**
   * 禁用插件
   * @param {string} name - 插件名称
   */
  async disablePlugin(name) {
    await this.pluginManager.disable(name);
    return this;
  }

  /**
   * 更新插件配置
   * @param {string} name - 插件名称
   * @param {Object} config - 新配置
   */
  updatePluginConfig(name, config) {
    return this.pluginManager.updatePluginConfig(name, config);
  }

  /**
   * 注册工具
   * @param {Object} tool - 工具定义
   */
  registerTool(tool) {
    this.toolRegistry.register(tool);
    return this;
  }

  /**
   * 获取所有工具）
   * @returns {Array<Object>}
   */
  getTools() {
    return this.toolRegistry.getAll();
  }

  // ============================================================================
  // 事件描述注册（供 Ambient Agent 使用）
  // ============================================================================

  /**
   * 注册事件描述
   * @param {string} eventType - 事件类型，如 'tool:result'
   * @param {string} description - 事件描述
   * @param {Object} schema - 事件参数 Schema（可选）
   */
  registerEventDescription(eventType, description, schema = null) {
    this.pluginManager.registerEventDescription(eventType, description, schema);
    return this;
  }

  /**
   * 获取所有已注册的事件描述
   * @returns {Map<string, Object>} 事件描述 Map
   */
  getEventDescriptions() {
    return this.pluginManager.getEventDescriptions();
  }

  /**
   * 获取单个事件描述
   * @param {string} eventType - 事件类型
   * @returns {Object|null} 事件描述
   */
  getEventDescription(eventType) {
    return this.pluginManager.getEventDescription(eventType);
  }

  /**
   * 执行工具
   * @param {string} name - 工具名称
   * @param {Object} args - 参数
   */
  async executeTool(name, args) {
    return this.toolRegistry.execute(name, args, this);
  }

  /**
   * 在上下文中执行函数（支持并行处理，自动隔离 session）
   * @param {Object} context - 执行上下文 { sessionId, ... }
   * @param {Function} fn - 要执行的异步函数
   * @returns {Promise}
   */
  runWithContext(context, fn) {
    return asyncLocalStorage.run(context, fn);
  }

  /**
   * 获取当前执行上下文（在 runWithContext 内部调用）
   * @returns {Object|null}
   */
  getExecutionContext() {
    return asyncLocalStorage.getStore() || null;
  }

  /**
   * @deprecated 使用 runWithContext 代替
   */
  setExecutionContext() {}

  /**
   * @deprecated 使用 runWithContext 代替
   */
  clearExecutionContext() {}

  // ============================================================================
  // 分层上下文系统 - Session Context
  // ============================================================================

  /**
   * 获取或创建 SessionContext
   * @param {string} sessionId - 会话 ID
   * @param {Object} options - 配置选项
   * @returns {SessionContext}
   */
  getOrCreateSessionContext(sessionId, options = {}) {
    if (!sessionId) {
      return null;
    }

    // 先检查内存缓存
    let ctx = this._sessionContexts.get(sessionId);
    if (ctx) {
      return ctx;
    }

    // 尝试从存储同步加载（仅文件存储支持）
    const storage = this._getSessionStorage();
    const loadedCtx = SessionContext.loadSync(sessionId, this, { ...options, storage });
    if (loadedCtx) {
      this._sessionContexts.set(sessionId, loadedCtx);
      this.emit('session:context-created', loadedCtx);
      return loadedCtx;
    }

    // 创建新的 SessionContext
    ctx = new SessionContext(sessionId, this, { ...options, storage });
    this._sessionContexts.set(sessionId, ctx);
    this.emit('session:context-created', ctx);
    return ctx;
  }

  /**
   * 异步加载 SessionContext（如果存在）
   * @param {string} sessionId
   * @param {Object} options
   * @returns {Promise<SessionContext|null>}
   */
  async loadSessionContext(sessionId, options = {}) {
    if (!sessionId) {
      return null;
    }

    // 先检查内存缓存
    let ctx = this._sessionContexts.get(sessionId);
    if (ctx) {
      return ctx;
    }

    const storage = this._getSessionStorage();
    ctx = await SessionContext.load(sessionId, this, { ...options, storage });
    if (ctx) {
      this._sessionContexts.set(sessionId, ctx);
      this.emit('session:context-created', ctx);
    }
    return ctx;
  }

  /**
   * 获取 Session 存储适配器
   * @returns {SessionStorageAdapter}
   * @private
   */
  _getSessionStorage() {
    if (!this._sessionStorage) {
      this._sessionStorage = new SessionStorageAdapter(this._sessionStorageConfig);
    }
    return this._sessionStorage;
  }

  /**
   * 配置 Session 存储类型
   * @param {Object} config - 存储配置
   * @param {string} [config.type='memory'] - 存储类型: 'memory', 'file'
   * @param {string} [config.baseDir='.agent/sessions'] - 文件存储目录
   */
  configureSessionStorage(config) {
    this._sessionStorageConfig = config;
    this._sessionStorage = new SessionStorageAdapter(config);
  }

  /**
   * 获取当前 Session 存储适配器
   * @returns {SessionStorageAdapter}
   */
  getSessionStorage() {
    return this._getSessionStorage();
  }

  /**
   * 获取 SessionContext
   * @param {string} sessionId - 会话 ID
   * @returns {SessionContext|null}
   */
  getSessionContext(sessionId) {
    return this._sessionContexts.get(sessionId) || null;
  }

  /**
   * 获取当前 Session 上下文（从 AsyncLocalStorage 获取）
   * @returns {SessionContext|null}
   */
  getCurrentSessionContext() {
    const store = sessionStorage.getStore();
    return store?.sessionContext || null;
  }

  /**
   * 获取当前 sessionId（从 AsyncLocalStorage 获取）
   * @returns {string|null}
   */
  getCurrentSessionId() {
    const store = sessionStorage.getStore();
    return store?.sessionId || null;
  }

  /**
   * 在 Session 上下文中执行函数
   * @param {string} sessionId - 会话 ID
   * @param {Object} options - Session 选项
   * @param {Function} fn - 异步函数
   * @returns {Promise}
   */
  runInSession(sessionId, options, fn) {
    if (!sessionId) {
      // 无 session，直接执行
      return fn();
    }

    const sessionCtx = this.getOrCreateSessionContext(sessionId, options);
    const context = { sessionContext: sessionCtx, sessionId };
    return sessionStorage.run(context, fn);
  }

  /**
   * 销毁 Session Context
   * @param {string} sessionId
   */
  destroySessionContext(sessionId) {
    if (this._sessionContexts.has(sessionId)) {
      const ctx = this._sessionContexts.get(sessionId);
      ctx.destroy();
      this._sessionContexts.delete(sessionId);

      // 从存储中删除
      if (this._sessionStorage) {
        this._sessionStorage.delete(sessionId).catch(() => {});
      }

      this.emit('session:context-destroyed', ctx);
    }
  }

  /**
   * 列出所有活跃的 Session ID
   * @returns {string[]}
   */
  listActiveSessions() {
    return Array.from(this._sessionContexts.keys());
  }

  // ============================================================================
  // 分层上下文系统 - Request Context
  // ============================================================================

  /**
   * 获取当前 Request 上下文
   * @returns {Object|null}
   */
  getRequestContext() {
    return requestStorage.getStore() || null;
  }

  /**
   * 在 Request 上下文中执行函数
   * @param {Object} context - Request 上下文
   * @param {Function} fn - 异步函数
   * @returns {Promise}
   */
  runWithRequestContext(context, fn) {
    return requestStorage.run(context, fn);
  }

  // ============================================================================
  // 分层上下文系统 - Agent Context
  // ============================================================================

  /**
   * 获取当前 Agent 上下文
   * @returns {Object|null}
   */
  getAgentContext() {
    return agentStorage.getStore()?.agentContext || null;
  }

  /**
   * 在 Agent 上下文中执行函数
   * @param {string} agentId - Agent ID
   * @param {Object} context - Agent 上下文
   * @param {Function} fn - 异步函数
   * @returns {Promise}
   */
  runWithAgentContext(agentId, context, fn) {
    return agentStorage.run({ agentId, ...context }, fn);
  }

  // ============================================================================
  // 组合上下文
  // ============================================================================

  /**
   * 在完整上下文中执行（Request + Session）
   * @param {Object} requestOptions - Request 选项
   * @param {string} sessionId - Session ID
   * @param {Function} fn - 异步函数
   * @returns {Promise}
   */
  async runInContext(requestOptions, sessionId, fn) {
    const sessionCtx = sessionId ? this.getOrCreateSessionContext(sessionId) : null;

    return requestStorage.run(requestOptions, () => {
      if (sessionCtx) {
        return sessionStorage.run({ sessionContext: sessionCtx, sessionId }, fn);
      }
      return fn();
    });
  }

  /**
   * 创建 Agent
   * @param {Object} config - Agent 配置
   */
  createAgent(config) {
    // 合并 AI 插件配置
    config = this._mergeAIConfig(config);

    const agent = new Agent(this, config);

    // 跟踪 agent
    this._agents.push(agent);
    if (!this._mainAgent) {
      this._mainAgent = agent;
    }

    this.emit('agent:created', agent);
    return agent;
  }

  /**
   * 为指定 session 创建独立 Agent 实例
   * @param {string} sessionId - session ID
   * @param {Object} config - Agent 配置
   */
  createSessionAgent(sessionId, config = {}) {
    const agentConfig = {
      name: `session_${sessionId}`,
      ...config,
    };

    // 合并 AI 插件配置
    const merged = this._mergeAIConfig(agentConfig);

    const agent = new Agent(this, merged);
    this._agents.push(agent);

    // 如果提供了 systemPrompt，需要替换 AgentChatHandler
    if (merged.systemPrompt) {
      agent.setSystemPrompt(merged.systemPrompt);
    }

    this.emit('agent:created', agent);
    return agent;
  }

  /**
   * 创建子Agent（具有独立工具集的轻量级Agent）
   * @param {Object} config - 子Agent配置
   * @param {string} config.name - 子Agent名称
   * @param {string} config.role - 角色描述（用于智能选择）
   * @param {string} [config.description] - 供主Agent理解的描述）
   * @param {Object} [config.tools] - 自定义工具 { name: toolDef }
   * @param {string[]} [config.parentTools] - 从父Agent继承的工具名称列表）
   * @param {Object} [config.llmConfig] - 独立LLM配置
   * @returns {Agent} 创建的子Agent
   */
  createSubAgent(config) {
    const {
      name,
      role,
      description = '',
      tools = {},
      parentTools, // 如果不传，默认继承主agent所有工具
      llmConfig = null,
    } = config;

    // 构建子Agent配置
    const agentConfig = {
      name: `subagent_${name}`,
      role: role,
      systemPrompt: role, // 使用 role 作为 systemPrompt
      ...(llmConfig || {}), // 如果提供了独立LLM配置，合并
    };

    // 合并 AI 插件配置
    const merged = this._mergeAIConfig(agentConfig);

    // 创建 Agent
    const agent = new Agent(this, merged);

    // 注册自定义工具
    for (const [toolName, toolDef] of Object.entries(tools)) {
      if (toolDef && typeof toolDef === 'object') {
        agent.registerTool({
          name: toolName,
          description: toolDef.description || '',
          inputSchema: toolDef.inputSchema,
          execute: toolDef.execute,
        });
      }
    }

    // 从父Agent继承工具
    if (this._mainAgent) {
      const parentToolsDefs = this._mainAgent.getTools();
      if (parentTools === undefined) {
        // 如果没有指定 parentTools，默认继承所有工具
        for (const toolDef of parentToolsDefs) {
          agent.registerTool(toolDef);
        }
      } else if (Array.isArray(parentTools) && parentTools.length > 0) {
        // 指定了要继承的工具列表
        for (const toolName of parentTools) {
          const toolDef = parentToolsDefs.find((t) => t.name === toolName);
          if (toolDef) {
            agent.registerTool(toolDef);
          }
        }
      }
    }

    this._agents.push(agent);
    this.emit('agent:created', agent);
    return agent;
  }

  /**
   * 获取 AI 插件
   * @returns {Object|undefined}
   */
  getAIPlugin() {
    return this.pluginManager.get('ai');
  }

  /**
   * Bootstrap - 使用默认配置启动框架
   * 自动加载 .agent/ 目录下的配置和所有默认插件）
   * @param {Object} config - 配置
   * @param {string} [config.agentDir='.agent'] - Agent 配置目录
   * @param {Object} [config.aiConfig] - AI 配置（可选，覆盖文件配置）
   * @returns {Promise<Framework>}
   */
  async bootstrap(config = {}) {
    const {
      bootstrapDefaults,
      DefaultPlugins,
      loadAgentConfig,
    } = require('../../plugins/default-plugins');

    // 先加载默认插件配置
    const defaultsPlugin = new DefaultPlugins({
      agentDir: config.agentDir || '.agent',
    });

    await this.loadPlugin(defaultsPlugin);

    // 获取配置
    const agentConfig = defaultsPlugin.getConfig();

    // 如果提供了 AI 配置，覆盖文件配置
    if (config.aiConfig) {
      agentConfig.ai = { ...agentConfig.ai, ...config.aiConfig };
    }

    // 加载所有默认插件（传入已加载的配置避免重复加载）
    await bootstrapDefaults(this, { _config: agentConfig, _skipConfigLoad: true });

    this._setReady();
    return this;
  }

  /**
   * 等待框架就绪
   */
  async ready() {
    if (this._ready) {
      return this;
    }

    if (!this._readyPromise) {
      this._readyPromise = new Promise((resolve) => {
        this._resolveReady = resolve;
      });
    }

    await this._readyPromise;
    return this;
  }

  /**
   * 标记框架就绪
   * @private
   */
  _setReady() {
    this._ready = true;
    if (this._resolveReady) {
      this._resolveReady(this);
    }
    this.emit('framework:ready', this);
  }

  /**
   * 注册内置工具
   * @private
   */
  _registerBuiltinTools() {
    // 内置工具会在 Agent 创建时添加）
  }

  // ============================================================================
  // Coordinator 模式管理
  // ============================================================================

  /**
   * 初始化Coordinator管理器
   * @param {Agent} coordinatorAgent - Coordinator Agent实例
   */
  initCoordinatorManager(coordinatorAgent) {
    if (!this._coordinatorManager) {
      this._coordinatorManager = new CoordinatorManager(this);
    }
    this._coordinatorManager.setCoordinatorAgent(coordinatorAgent);
    return this._coordinatorManager;
  }

  /**
   * 获取Coordinator管理器
   * @returns {CoordinatorManager|null}
   */
  getCoordinatorManager() {
    return this._coordinatorManager;
  }

  /**
   * 创建Worker（由coordinator-plugin调用）
   * @param {Object} config - Worker配置
   * @param {string} config.name - Worker名称
   * @param {string} config.task - 初始任务
   * @param {string} [config.systemPrompt] - 可选系统提示
   * @param {string[]} [config.tools] - 可用工具列表
   * @returns {Promise<{workerId: string, status: string}>}
   */
  async createWorker(config) {
    if (!this._coordinatorManager) {
      throw new Error('CoordinatorManager not initialized. Call initCoordinatorManager first.');
    }
    return this._coordinatorManager.createWorker(config);
  }

  /**
   * 销毁框架
   */
  async destroy() {
    // 销毁Coordinator管理器
    if (this._coordinatorManager) {
      this._coordinatorManager.destroy();
      this._coordinatorManager = null;
    }

    // 刷新所有 Session 存储
    if (this._sessionStorage) {
      await this._sessionStorage.flush();
      await this._sessionStorage.destroy();
    }

    // 卸载所有插件
    const plugins = this.pluginManager.getAll();
    for (const { name } of plugins) {
      await this.pluginManager.unload(name);
    }

    // 清空工具
    this.toolRegistry.clear();

    // 清空事件
    this.removeAllListeners();

    this.emit('framework:destroyed');
  }
}

module.exports = { Framework };
