/**
 * CoordinatorManager - Coordinator模式管理器
 * 管理Worker的创建、消息传递、生命周期
 */

const { EventEmitter } = require('../utils/event-emitter');
const { WorkerAgent } = require('./worker-agent');
const { logger } = require('../utils/logger');

const log = logger.child('CoordinatorManager');

/**
 * Worker上下文
 */
class WorkerContext {
  constructor(config) {
    this.workerId = config.workerId;
    this.name = config.name;
    this.coordinatorId = config.coordinatorId;
    this.task = config.task;
    this.status = 'pending'; // pending, running, completed, error, stopped
    this.agent = config.agent;
    this.tools = config.tools || [];
    this.createdAt = new Date();
    this.updatedAt = new Date();
    this.result = null;
    this.error = null;
  }

  update(status, result = null, error = null) {
    this.status = status;
    this.result = result;
    this.error = error;
    this.updatedAt = new Date();
  }
}

/**
 * CoordinatorManager - 管理所有Worker
 */
class CoordinatorManager extends EventEmitter {
  /**
   * @param {Framework} framework - 框架实例
   */
  constructor(framework) {
    super();
    this.framework = framework;
    this._workers = new Map(); // workerId -> WorkerContext
    this._nameIndex = new Map(); // name -> workerId
    this._coordinatorAgent = null; // Coordinator Agent实例
  }

  /**
   * 设置Coordinator Agent
   * @param {Agent} agent - Coordinator Agent实例
   */
  setCoordinatorAgent(agent) {
    this._coordinatorAgent = agent;
  }

  /**
   * 获取Coordinator Agent
   */
  getCoordinatorAgent() {
    return this._coordinatorAgent;
  }

  /**
   * 创建Worker
   * @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) {
    const { name, task, systemPrompt, tools } = config;

    // 检查名称唯一性
    if (this._nameIndex.has(name)) {
      throw new Error(`Worker with name '${name}' already exists`);
    }

    // 生成workerId
    const workerId = `worker_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;

    // 获取AI配置
    const aiPlugin = this.framework.pluginManager.get('ai');
    const aiConfig = aiPlugin ? aiPlugin.getConfig() : {};

    // 构建系统提示
    let finalSystemPrompt = systemPrompt;
    if (!finalSystemPrompt) {
      finalSystemPrompt = WorkerAgent.defaultPrompt();
    }

    // 创建WorkerAgent
    const agentConfig = {
      workerId,
      coordinatorId: this._coordinatorAgent?.name || 'unknown',
      name: `worker_${name}`,
      task,
      systemPrompt: finalSystemPrompt,
      tools: tools || [],
      model: aiConfig.model,
      provider: aiConfig.provider,
      apiKey: aiConfig.apiKey,
      baseURL: aiConfig.baseURL,
    };

    const workerAgent = new WorkerAgent(this.framework, agentConfig);

    // 创建WorkerContext
    const context = new WorkerContext({
      workerId,
      name,
      coordinatorId: this._coordinatorAgent?.name || 'unknown',
      task,
      agent: workerAgent,
      tools: tools || [],
    });

    // 保存
    this._workers.set(workerId, context);
    this._nameIndex.set(name, workerId);

    // 监听Worker事件
    workerAgent.on('message', (msg) => {
      this._handleWorkerMessage(workerId, msg);
    });

    workerAgent.on('stopped', () => {
      this._handleWorkerStopped(workerId);
    });

    // 发送初始任务
    context.status = 'running';
    this.emit('worker:created', { workerId, name, status: 'running' });
    this.emit('worker:started', { workerId, name, task });

    // 异步执行任务（不等待完成）
    this._runWorkerTask(workerId, task);

    return { workerId, status: 'running' };
  }

  /**
   * 异步执行Worker任务
   * @private
   */
  async _runWorkerTask(workerId, task) {
    const context = this._workers.get(workerId);
    if (!context) return;

    try {
      const result = await context.agent.runTask(task);
      context.update('completed', result);

      // 生成通知
      const notification = this._generateCompletionNotification(workerId, 'completed', result);
      this.emit('worker:completed', { workerId, name: context.name, result, notification });
    } catch (err) {
      context.update('error', null, err.message);
      const notification = this._generateCompletionNotification(
        workerId,
        'error',
        null,
        err.message
      );
      this.emit('worker:error', { workerId, name: context.name, error: err.message, notification });
    }
  }

  /**
   * 处理Worker消息
   * @private
   */
  _handleWorkerMessage(workerId, msg) {
    const context = this._workers.get(workerId);
    if (!context) return;

    this.emit('worker:message', { workerId, name: context.name, message: msg });

    // 转发给Coordinator（如果有）
    if (this._coordinatorAgent) {
      this._coordinatorAgent.emit('worker:message', { workerId, name: context.name, message: msg });
    }
  }

  /**
   * 处理Worker停止
   * @private
   */
  _handleWorkerStopped(workerId) {
    const context = this._workers.get(workerId);
    if (!context) return;

    context.update('stopped');
    this.emit('worker:stopped', { workerId, name: context.name });

    // 清理索引
    this._nameIndex.delete(context.name);
  }

  /**
   * 发送消息给Worker（继续执行）
   * @param {string} workerName - Worker名称
   * @param {string} message - 消息内容
   * @returns {Promise<Object>} 处理结果
   */
  async sendToWorker(workerName, message) {
    const workerId = this._nameIndex.get(workerName);
    if (!workerId) {
      throw new Error(`Worker '${workerName}' not found`);
    }

    const context = this._workers.get(workerId);
    if (!context) {
      throw new Error(`Worker context not found for '${workerName}'`);
    }

    if (context.status === 'stopped') {
      throw new Error(`Worker '${workerName}' has been stopped`);
    }

    this.emit('worker:resumed', { workerId, name: workerName, message });

    try {
      const result = await context.agent.sendMessage(message);
      return result;
    } catch (err) {
      context.update('error', null, err.message);
      throw err;
    }
  }

  /**
   * 停止Worker
   * @param {string} workerName - Worker名称
   * @param {string} [reason] - 停止原因
   * @returns {Object} 停止结果
   */
  stopWorker(workerName, reason = null) {
    const workerId = this._nameIndex.get(workerName);
    if (!workerId) {
      throw new Error(`Worker '${workerName}' not found`);
    }

    const context = this._workers.get(workerId);
    if (!context) {
      throw new Error(`Worker context not found for '${workerName}'`);
    }

    context.agent.stop();
    context.update('stopped');

    const notification = this._generateCompletionNotification(workerId, 'stopped', null, reason);
    this.emit('worker:stopped', {
      workerId,
      name: workerName,
      reason,
      notification,
    });

    // 清理索引
    this._nameIndex.delete(workerName);

    return { workerId, name: workerName, status: 'stopped', reason };
  }

  /**
   * 获取Worker状态
   * @param {string} workerName - Worker名称
   * @returns {Object|null} Worker信息
   */
  getWorker(workerName) {
    const workerId = this._nameIndex.get(workerName);
    if (!workerId) return null;

    const context = this._workers.get(workerId);
    if (!context) return null;

    return {
      workerId: context.workerId,
      name: context.name,
      status: context.status,
      task: context.task,
      result: context.result,
      error: context.error,
      createdAt: context.createdAt,
      updatedAt: context.updatedAt,
    };
  }

  /**
   * 列出所有Worker
   * @returns {Array} Worker列表
   */
  listWorkers() {
    const workers = [];
    for (const [workerId, context] of this._workers) {
      // 跳过已停止的
      if (context.status === 'stopped') continue;

      workers.push({
        workerId: context.workerId,
        name: context.name,
        status: context.status,
        task: context.task,
        createdAt: context.createdAt,
        updatedAt: context.updatedAt,
      });
    }
    return workers;
  }

  /**
   * 生成完成通知XML
   * @private
   */
  _generateCompletionNotification(workerId, status, result, error = null) {
    return WorkerAgent.formatNotification(workerId, status, result, error);
  }

  /**
   * 销毁所有Worker
   */
  destroy() {
    for (const [workerId, context] of this._workers) {
      if (context.status !== 'stopped') {
        context.agent.stop();
      }
    }
    this._workers.clear();
    this._nameIndex.clear();
    this._coordinatorAgent = null;
  }
}

module.exports = { CoordinatorManager, WorkerContext };
