// 任务编排引擎 - 实现类
import type {
  TaskOrchestrationEngine,
  TaskPlan,
  TaskStep,
  ExecutionResult,
  Progress,
  StepStatus
} from './types';
import { generateId } from '../../utils/id';
import { createLogger } from '../../utils/logger';

const log = createLogger('TaskOrchestrator');

export class TaskOrchestrator implements TaskOrchestrationEngine {
  private plans: Map<string, TaskPlan> = new Map();

  async plan(goal: string, context: any): Promise<TaskPlan> {
    // TODO: 使用 AI 规划任务（后续实现）
    // 这里先返回一个简单的示例计划
    const steps: TaskStep[] = [
      {
        id: 'step_1',
        description: '分析任务需求',
        tool: 'ai',
        params: { goal },
        dependencies: [],
        status: 'pending'
      },
      {
        id: 'step_2',
        description: '执行任务',
        tool: 'executor',
        params: { goal },
        dependencies: ['step_1'],
        status: 'pending'
      },
      {
        id: 'step_3',
        description: '整理结果',
        tool: 'combiner',
        params: {},
        dependencies: ['step_2'],
        status: 'pending'
      }
    ];

    const plan: TaskPlan = {
      id: this.generateId(),
      goal,
      steps,
      dependencies: new Map(),
      context: new Map(Object.entries(context)),
      status: 'planned',
      progress: 0
    };

    this.plans.set(plan.id, plan);
    log.info(`Plan created: ${plan.id} with ${steps.length} steps`);
    
    return plan;
  }

  async execute(plan: TaskPlan): Promise<ExecutionResult> {
    plan.status = 'executing';
    
    try {
      // 拓扑排序
      const sortedSteps = this.topologicalSort(plan.steps);
      
      for (const step of sortedSteps) {
        // 检查依赖
        await this.waitForDependencies(step, plan);
        
        // 执行步骤
        step.status = 'running';
        plan.progress = this.calculateProgress(plan);
        
        log.info(`Executing step: ${step.id} - ${step.description}`);
        
        // TODO: 实际执行逻辑（后续实现）
        await new Promise(resolve => setTimeout(resolve, 500));
        
        step.status = 'completed';
        step.result = { message: 'Step completed' };
        
        plan.progress = this.calculateProgress(plan);
      }
      
      plan.status = 'completed';
      plan.progress = 1;
      
      return {
        planId: plan.id,
        status: 'completed',
        results: plan.steps.map(s => s.result)
      };
      
    } catch (error: any) {
      plan.status = 'failed';
      throw error;
    }
  }

  async getProgress(planId: string): Promise<Progress> {
    const plan = this.plans.get(planId);
    if (!plan) {
      throw new Error(`Plan not found: ${planId}`);
    }

    const completed = plan.steps.filter(s => s.status === 'completed').length;
    const percentage = (plan.progress * 100).toFixed(1) + '%';

    return {
      planId: plan.id,
      goal: plan.goal,
      total: plan.steps.length,
      completed,
      current: plan.steps.find(s => s.status === 'running')?.description || '',
      percentage,
      steps: plan.steps.map(s => ({
        description: s.description,
        status: s.status,
        result: s.result
      }))
    };
  }

  async pause(planId: string): Promise<void> {
    const plan = this.plans.get(planId);
    if (plan) {
      plan.status = 'paused';
    }
  }

  async resume(planId: string): Promise<void> {
    const plan = this.plans.get(planId);
    if (plan && plan.status === 'paused') {
      plan.status = 'executing';
      // 继续执行（后续实现）
    }
  }

  async cancel(planId: string): Promise<void> {
    const plan = this.plans.get(planId);
    if (plan) {
      plan.status = 'failed';
    }
  }

  private topologicalSort(steps: TaskStep[]): TaskStep[] {
    // 简单实现：按依赖顺序排序
    const sorted: TaskStep[] = [];
    const visited = new Set<string>();

    const visit = (step: TaskStep) => {
      if (visited.has(step.id)) return;
      visited.add(step.id);

      for (const depId of step.dependencies) {
        const dep = steps.find(s => s.id === depId);
        if (dep) visit(dep);
      }

      sorted.push(step);
    };

    steps.forEach(visit);
    return sorted;
  }

  private async waitForDependencies(step: TaskStep, plan: TaskPlan): Promise<void> {
    for (const depId of step.dependencies) {
      const dep = plan.steps.find(s => s.id === depId);
      if (dep && dep.status !== 'completed') {
        // 等待依赖完成（简单实现）
        await new Promise(resolve => setTimeout(resolve, 100));
      }
    }
  }

  private calculateProgress(plan: TaskPlan): number {
    const completed = plan.steps.filter(s => s.status === 'completed').length;
    return completed / plan.steps.length;
  }

  listPlans(filter?: { status?: string }): TaskPlan[] {
    let plans = Array.from(this.plans.values());
    if (filter?.status) plans = plans.filter(p => p.status === filter.status);
    return plans;
  }

  private generateId(): string {
    return generateId('plan');
  }
}
