/**
 * ExecutionStepManager - 可扩展的步骤执行框架
 * 
 * 提供步骤的动态添加、管理和执行，支持错误处理和状态回调
 * 
 * 主要功能：
 * - 步骤的动态添加和管理
 * - 支持重试机制和错误处理
 * - 提供执行状态回调
 * - 支持并行和串行执行
 * - 可扩展的步骤定义
 * 
 * @author Financial Analysis Platform Team
 * @version 1.0.0
 */

// ============================================================================
// 类型定义
// ============================================================================

/**
 * 执行步骤接口
 */
export interface ExecutionStep {
  /** 步骤唯一标识符 */
  id: string;
  /** 步骤显示名称 */
  name: string;
  /** 步骤详细描述 */
  description: string;
  /** 执行函数（可选） */
  execute?: () => Promise<void>;
}

/**
 * 执行选项接口
 */
export interface ExecutionOptions {
  /** 步骤开始回调 */
  onStepStart?: (step: ExecutionStep, index: number, total: number) => void;
  /** 步骤完成回调 */
  onStepComplete?: (step: ExecutionStep, index: number, total: number) => void;
  /** 步骤错误回调 */
  onStepError?: (step: ExecutionStep, index: number, total: number, error: Error) => void;
  /** 全部完成回调 */
  onComplete?: () => void;
  /** 执行错误回调 */
  onError?: (error: Error) => void;
  /** 最大重试次数 */
  maxRetries?: number;
  /** 重试延迟（毫秒） */
  retryDelay?: number;
  /** 出错时是否继续执行 */
  continueOnError?: boolean;
}

/**
 * 执行上下文接口
 */
export interface ExecutionContext {
  /** 当前执行步骤 */
  currentStep: ExecutionStep | null;
  /** 当前步骤索引 */
  stepIndex: number;
  /** 总步骤数 */
  totalSteps: number;
  /** 是否正在运行 */
  isRunning: boolean;
  /** 是否有错误 */
  hasError: boolean;
  /** 错误信息 */
  errorMessage?: string;
  /** 重试次数 */
  retryCount: number;
  /** 最大重试次数 */
  maxRetries: number;
  /** 是否可重试 */
  canRetry: boolean;
}

export class ExecutionStepManager {
  private steps: ExecutionStep[] = [];
  private context: ExecutionContext = {
    currentStep: null,
    stepIndex: 0,
    totalSteps: 0,
    isRunning: false,
    hasError: false,
    errorMessage: undefined,
    retryCount: 0,
    maxRetries: 0,
    canRetry: false
  };
  private options: ExecutionOptions = {};

  constructor(steps: ExecutionStep[] = [], options: ExecutionOptions = {}) {
    this.steps = [...steps];
    this.options = {
      maxRetries: 2,
      retryDelay: 1000,
      continueOnError: false,
      ...options
    };
    this.updateContext();
  }

  /**
   * 添加执行步骤
   */
  addStep(step: ExecutionStep): void {
    this.steps.push(step);
    this.updateContext();
  }

  /**
   * 批量添加执行步骤
   */
  addSteps(steps: ExecutionStep[]): void {
    this.steps.push(...steps);
    this.updateContext();
  }

  /**
   * 插入步骤到指定位置
   */
  insertStep(index: number, step: ExecutionStep): void {
    this.steps.splice(index, 0, step);
    this.updateContext();
  }

  /**
   * 移除步骤
   */
  removeStep(stepId: string): boolean {
    const index = this.steps.findIndex(step => step.id === stepId);
    if (index !== -1) {
      this.steps.splice(index, 1);
      this.updateContext();
      return true;
    }
    return false;
  }

  /**
   * 清空所有步骤
   */
  clearSteps(): void {
    this.steps = [];
    this.updateContext();
  }

  /**
   * 获取所有步骤
   */
  getSteps(): ExecutionStep[] {
    return [...this.steps];
  }

  /**
   * 获取当前执行上下文
   */
  getContext(): ExecutionContext {
    return { ...this.context };
  }

  /**
   * 更新执行选项
   */
  setOptions(options: ExecutionOptions): void {
    this.options = { ...this.options, ...options };
  }

  /**
   * 执行所有步骤
   */
  async execute(): Promise<void> {
    if (this.context.isRunning) {
      throw new Error('Execution is already in progress');
    }

    if (this.steps.length === 0) {
      throw new Error('No steps to execute');
    }

    this.context.isRunning = true;
    this.context.hasError = false;
    this.context.errorMessage = undefined;
    this.context.stepIndex = 0;
    this.context.retryCount = 0;
    this.context.maxRetries = this.options.maxRetries || 2;

    try {
      for (let i = 0; i < this.steps.length; i++) {
        const step = this.steps[i];
        this.context.currentStep = step;
        this.context.stepIndex = i;

        // 通知步骤开始
        this.options.onStepStart?.(step, i, this.steps.length);

        let stepSuccess = false;
        let lastError: Error | null = null;

        // 重试逻辑
        for (let retryAttempt = 0; retryAttempt <= this.context.maxRetries; retryAttempt++) {
          try {
            this.context.retryCount = retryAttempt;
            
            // 如果是重试，等待一段时间
            if (retryAttempt > 0 && this.options.retryDelay) {
              await new Promise(resolve => setTimeout(resolve, this.options.retryDelay));
            }

            // 执行步骤（如果有执行函数）
            if (step.execute) {
              await step.execute();
            }

            stepSuccess = true;
            break; // 成功执行，跳出重试循环
          } catch (stepError) {
            lastError = stepError instanceof Error ? stepError : new Error(String(stepError));
            
            // 如果还有重试机会，继续重试
            if (retryAttempt < this.context.maxRetries) {
              console.warn(`Step "${step.name}" failed, retrying (${retryAttempt + 1}/${this.context.maxRetries + 1}):`, lastError.message);
              continue;
            }
          }
        }

        if (stepSuccess) {
          // 通知步骤完成
          this.options.onStepComplete?.(step, i, this.steps.length);
        } else {
          // 所有重试都失败了
          const error = lastError || new Error('Step execution failed');
          
          // 更新错误状态
          this.context.hasError = true;
          this.context.errorMessage = error.message;
          this.context.canRetry = true;

          // 通知步骤错误
          this.options.onStepError?.(step, i, this.steps.length, error);

          // 如果不继续执行，抛出错误
          if (!this.options.continueOnError) {
            throw error;
          }
        }
      }

      // 所有步骤执行完成
      this.options.onComplete?.();
    } catch (error) {
      const execError = error instanceof Error ? error : new Error(String(error));
      
      // 通知执行错误
      this.options.onError?.(execError);
      
      // 重新抛出错误
      throw execError;
    } finally {
      this.context.isRunning = false;
    }
  }

  /**
   * 执行单个步骤
   */
  async executeStep(stepId: string): Promise<void> {
    const stepIndex = this.steps.findIndex(step => step.id === stepId);
    if (stepIndex === -1) {
      throw new Error(`Step with id '${stepId}' not found`);
    }

    const step = this.steps[stepIndex];
    this.context.currentStep = step;
    this.context.stepIndex = stepIndex;
    this.context.isRunning = true;
    this.context.hasError = false;
    this.context.errorMessage = undefined;

    try {
      // 通知步骤开始
      this.options.onStepStart?.(step, stepIndex, this.steps.length);

      // 执行步骤
      if (step.execute) {
        await step.execute();
      }

      // 通知步骤完成
      this.options.onStepComplete?.(step, stepIndex, this.steps.length);
    } catch (stepError) {
      const error = stepError instanceof Error ? stepError : new Error(String(stepError));
      
      // 更新错误状态
      this.context.hasError = true;
      this.context.errorMessage = error.message;

      // 通知步骤错误
      this.options.onStepError?.(step, stepIndex, this.steps.length, error);

      throw error;
    } finally {
      this.context.isRunning = false;
    }
  }

  /**
   * 停止执行（如果正在运行）
   */
  stop(): void {
    this.context.isRunning = false;
  }

  /**
   * 重试当前失败的步骤
   */
  async retry(): Promise<void> {
    if (!this.context.hasError || !this.context.canRetry) {
      throw new Error('No failed step to retry');
    }

    if (this.context.isRunning) {
      throw new Error('Execution is already in progress');
    }

    // 重置错误状态
    this.context.hasError = false;
    this.context.errorMessage = undefined;
    this.context.canRetry = false;

    // 重新执行从当前步骤开始
    try {
      await this.execute();
    } catch (error) {
      // 错误已经在execute方法中处理
      throw error;
    }
  }

  /**
   * 重置执行状态
   */
  reset(): void {
    this.context = {
      currentStep: null,
      stepIndex: 0,
      totalSteps: this.steps.length,
      isRunning: false,
      hasError: false,
      errorMessage: undefined,
      retryCount: 0,
      maxRetries: this.options.maxRetries || 2,
      canRetry: false
    };
  }

  /**
   * 检查是否正在执行
   */
  isRunning(): boolean {
    return this.context.isRunning;
  }

  /**
   * 检查是否有错误
   */
  hasError(): boolean {
    return this.context.hasError;
  }

  /**
   * 获取错误信息
   */
  getErrorMessage(): string | undefined {
    return this.context.errorMessage;
  }

  /**
   * 检查是否可以重试
   */
  canRetry(): boolean {
    return this.context.canRetry;
  }

  /**
   * 更新执行上下文
   */
  private updateContext(): void {
    this.context.totalSteps = this.steps.length;
    this.context.maxRetries = this.options.maxRetries || 2;
    if (!this.context.isRunning) {
      this.context.stepIndex = 0;
      this.context.currentStep = null;
      this.context.retryCount = 0;
    }
  }

  /**
   * 创建一个带有预定义步骤的管理器实例
   */
  static createWithSteps(steps: ExecutionStep[], options: ExecutionOptions = {}): ExecutionStepManager {
    return new ExecutionStepManager(steps, options);
  }

  /**
   * 创建一个空的管理器实例
   */
  static create(options: ExecutionOptions = {}): ExecutionStepManager {
    return new ExecutionStepManager([], options);
  }
}

/**
 * 预定义的执行步骤
 */
export const DEFAULT_EXECUTION_STEPS: ExecutionStep[] = [
  {
    id: 'fetch_financial_data',
    name: '正在读取财务数据',
    description: '从Tushare API获取公司财务指标数据'
  }
];

/**
 * 创建默认的执行步骤管理器
 */
export function createDefaultStepManager(options: ExecutionOptions = {}): ExecutionStepManager {
  return ExecutionStepManager.createWithSteps(DEFAULT_EXECUTION_STEPS, options);
}