/**
 * Task Orchestrator — 任务编排器
 *
 * 支持父子委派模式：主 Agent 委派子任务给 SubAgent。
 * 每个子任务运行一个独立的 AgentLoopEngine 实例。
 *
 * @see docs/生产级通用 AI Agent 智能体桌面应用：完整设计与构建指南.html — 第五章
 */

import { EventEmitter } from 'events';
import { nanoid } from 'nanoid';
import type { AgentLoopEngine } from '../agent-loop/engine';
import type { MetonaMessage, MetonaSystemPrompt } from '../types';
import type { ToolRegistry } from '../tools/registry';
import type { MetonaToolDef } from '../types';
import log from 'electron-log';

export interface SubAgentResult {
  taskId: string;
  result: string;
  success: boolean;
  durationMs: number;
}

interface SubAgentHandle {
  taskId: string;
  description: string;
  status: 'pending' | 'running' | 'completed' | 'error';
  result?: SubAgentResult;
  abort: () => void;
  onComplete: (callback: (result: SubAgentResult) => void) => void;
  onError: (callback: (error: Error) => void) => void;
  getStatus: () => { taskId: string; status: string; description: string };
}

export class TaskOrchestrator extends EventEmitter {
  private activeSubAgents = new Map<string, SubAgentHandle>();

  constructor(
    private agentLoopEngine: AgentLoopEngine,
    private toolRegistry?: ToolRegistry,
  ) {
    super();
  }

  /**
   * 委派子任务
   *
   * 创建一个独立的 SubAgent 执行上下文，调用 AgentLoopEngine 完成任务。
   * 支持限制可用工具列表（白名单）。
   */
  async delegate(params: {
    taskId?: string;
    description: string;
    parentSessionId: string;
    maxIterations?: number;
    tools?: string[];
  }): Promise<SubAgentResult> {
    const taskId = params.taskId ?? `sub_${nanoid(8)}`;
    const startMs = Date.now();

    this.emit('taskDelegated', { taskId, description: params.description, parentSessionId: params.parentSessionId });

    const handle: SubAgentHandle = {
      taskId,
      description: params.description,
      status: 'running',
      abort: () => {
        handle.status = 'error';
        this.activeSubAgents.delete(taskId);
      },
      onComplete: (callback) => {
        if (handle.result) callback(handle.result);
      },
      onError: (callback) => { /* errors captured by try/catch below */ },
      getStatus: () => ({ taskId, status: handle.status, description: handle.description }),
    };

    this.activeSubAgents.set(taskId, handle);
    this.emit('taskStarted', { taskId });

    try {
      // 构建用户消息
      const userMessage: MetonaMessage = {
        role: 'user',
        content: params.description,
        timestamp: Date.now(),
      };

      // 构建 System Prompt（子 Agent 简化版）
      const systemPrompt: MetonaSystemPrompt = {
        roleDefinition: '你是一个子任务执行 Agent，负责完成被委派的单一任务。',
        outputConstraints: '用中文回答，简洁准确地完成任务。',
        safetyGuidelines: '不访问工作空间外的文件，不执行危险命令。',
      };

      // 保存原始工具列表（子任务完成后恢复）
      const savedTools = this.agentLoopEngine.getTools?.() ?? [];

      // 如果指定了工具白名单，设置受限工具集
      if (params.tools && params.tools.length > 0 && this.toolRegistry) {
        const allowedTools: MetonaToolDef[] = [];
        for (const toolName of params.tools) {
          const tool = this.toolRegistry.get(toolName);
          if (tool) {
            allowedTools.push({
              name: tool.definition.name,
              description: tool.definition.description,
              parameters: tool.definition.parameters,
              category: tool.definition.category,
              riskLevel: tool.definition.riskLevel,
              requiresPermission: tool.definition.requiresPermission,
              timeoutMs: tool.definition.timeoutMs,
            });
          }
        }
        this.agentLoopEngine.setTools(allowedTools);
      }

      // 运行 Agent Loop（同步等待完成）
      let output;
      try {
        output = await this.agentLoopEngine.runStream(
          userMessage,
          taskId,
          [],  // 子 Agent 无历史
          systemPrompt,
        );
      } finally {
        // 恢复主 Agent 的原始工具列表
        this.agentLoopEngine.setTools(savedTools);
      }

      const durationMs = Date.now() - startMs;
      const success = output.terminationReason === 'completed';
      const result: SubAgentResult = {
        taskId,
        result: output.finalAnswer,
        success,
        durationMs,
      };

      handle.status = success ? 'completed' : 'error';
      handle.result = result;
      this.activeSubAgents.delete(taskId);
      this.emit('taskCompleted', result);

      log.info(`[Orchestrator] SubAgent "${taskId}" ${success ? 'completed' : 'failed'} in ${durationMs}ms`);

      return result;
    } catch (error) {
      const durationMs = Date.now() - startMs;
      const errMsg = (error as Error).message;
      const result: SubAgentResult = {
        taskId,
        result: errMsg,
        success: false,
        durationMs,
      };

      handle.status = 'error';
      handle.result = result;
      this.activeSubAgents.delete(taskId);
      this.emit('taskError', { taskId, error: errMsg });

      log.error(`[Orchestrator] SubAgent "${taskId}" error: ${errMsg}`);

      return result;
    }
  }

  /**
   * 完成子任务（外部触发）
   */
  completeTask(taskId: string, result: string, success: boolean): void {
    const handle = this.activeSubAgents.get(taskId);
    if (handle && handle.status === 'running') {
      handle.status = success ? 'completed' : 'error';
      handle.result = { taskId, result, success, durationMs: 0 };
      this.activeSubAgents.delete(taskId);
      this.emit('taskCompleted', handle.result);
    }
  }

  getActiveAgentsStatus(): Array<{ taskId: string; status: string; description: string }> {
    return Array.from(this.activeSubAgents.values()).map((a) => a.getStatus());
  }

  abortAll(): void {
    for (const agent of this.activeSubAgents.values()) {
      agent.abort();
    }
    this.activeSubAgents.clear();
  }
}
