import { DataFlow, NodeType, ProcessingStatus } from '../types/canvas';
import { aiService } from '../services/aiServices';

export interface BatchItem {
  id: string;
  filename: string;
  data: any;
  status: ProcessingStatus;
  result?: any;
  error?: string;
  thumbnail?: string;
  progress?: number;
}

export interface BatchProcessingOptions {
  concurrency: number; // 并发数
  retryAttempts: number; // 重试次数
  retryDelay: number; // 重试延迟(ms)
  onProgress?: (completed: number, total: number, currentItem?: BatchItem) => void;
  onItemComplete?: (item: BatchItem) => void;
  onItemError?: (item: BatchItem, error: string) => void;
}

/**
 * 批量处理引擎 - 支持并发处理和进度追踪
 */
export class BatchProcessor {
  private activeProcesses = new Map<string, AbortController>();
  private processingQueue: BatchItem[] = [];
  private completedItems: BatchItem[] = [];
  private failedItems: BatchItem[] = [];

  /**
   * 处理批量数据
   */
  async processBatch(
    items: any[],
    nodeType: NodeType,
    options: Partial<BatchProcessingOptions> = {}
  ): Promise<BatchItem[]> {
    const config: BatchProcessingOptions = {
      concurrency: 3,
      retryAttempts: 2,
      retryDelay: 1000,
      ...options
    };

    // 初始化批量项目
    const batchItems: BatchItem[] = items.map((item, index) => ({
      id: `batch-${Date.now()}-${index}`,
      filename: item.filename || item.name || `Item ${index + 1}`,
      data: item,
      status: 'idle' as ProcessingStatus
    }));

    this.processingQueue = [...batchItems];
    this.completedItems = [];
    this.failedItems = [];

    // 启动并发处理
    const workers = Array.from({ length: config.concurrency }, (_, i) =>
      this.processWorker(i, nodeType, config)
    );

    // 等待所有工作线程完成
    await Promise.all(workers);

    // 返回所有结果
    return [...this.completedItems, ...this.failedItems];
  }

  /**
   * 工作线程 - 处理队列中的项目
   */
  private async processWorker(
    workerId: number,
    nodeType: NodeType,
    config: BatchProcessingOptions
  ): Promise<void> {
    while (this.processingQueue.length > 0) {
      const item = this.processingQueue.shift();
      if (!item) break;

      // 更新状态为处理中
      item.status = 'loading';
      item.progress = 0;

      try {
        // 处理单个项目
        const result = await this.processItem(item, nodeType, config);
        
        // 成功完成
        item.status = 'success';
        item.result = result;
        item.progress = 100;
        item.thumbnail = this.generateThumbnail(result, nodeType);
        
        this.completedItems.push(item);
        config.onItemComplete?.(item);

      } catch (error) {
        // 处理失败
        item.status = 'error';
        item.error = error instanceof Error ? error.message : 'Processing failed';
        item.progress = 0;
        
        this.failedItems.push(item);
        config.onItemError?.(item, item.error);
      }

      // 更新总体进度
      const totalCompleted = this.completedItems.length + this.failedItems.length;
      const totalItems = totalCompleted + this.processingQueue.length;
      config.onProgress?.(totalCompleted, totalItems, item);
    }
  }

  /**
   * 处理单个项目
   */
  private async processItem(
    item: BatchItem,
    nodeType: NodeType,
    config: BatchProcessingOptions
  ): Promise<any> {
    const controller = new AbortController();
    this.activeProcesses.set(item.id, controller);

    try {
      let result: any;

      // 根据节点类型选择处理方法
      switch (nodeType) {
        case 'promptOptimize':
          result = await this.processPromptOptimize(item, controller.signal, config);
          break;
        case 'imageGenerate':
          result = await this.processImageGenerate(item, controller.signal, config);
          break;
        case 'imageEdit':
          result = await this.processImageEdit(item, controller.signal, config);
          break;
        case 'videoGenerate':
          result = await this.processVideoGenerate(item, controller.signal, config);
          break;
        default:
          throw new Error(`Unsupported batch processing for node type: ${nodeType}`);
      }

      return result;

    } finally {
      this.activeProcesses.delete(item.id);
    }
  }

  /**
   * 批量提示词优化
   */
  private async processPromptOptimize(
    item: BatchItem,
    signal: AbortSignal,
    config: BatchProcessingOptions
  ): Promise<string> {
    const prompt = typeof item.data === 'string' ? item.data : item.data.prompt || item.data.text;
    
    return await this.withRetry(
      () => aiService.optimizePrompt(prompt, {}, (progress) => {
        item.progress = progress;
      }),
      config.retryAttempts,
      config.retryDelay,
      signal
    );
  }

  /**
   * 批量图片生成
   */
  private async processImageGenerate(
    item: BatchItem,
    signal: AbortSignal,
    config: BatchProcessingOptions
  ): Promise<string> {
    const prompt = typeof item.data === 'string' ? item.data : item.data.prompt || item.data.text;
    
    return await this.withRetry(
      () => aiService.generateImage(prompt, {}, (progress) => {
        item.progress = progress;
      }),
      config.retryAttempts,
      config.retryDelay,
      signal
    );
  }

  /**
   * 批量图片编辑
   */
  private async processImageEdit(
    item: BatchItem,
    signal: AbortSignal,
    config: BatchProcessingOptions
  ): Promise<string> {
    const { imageUrl, instruction } = item.data;
    
    return await this.withRetry(
      () => aiService.editImage(imageUrl, instruction, {}, (progress) => {
        item.progress = progress;
      }),
      config.retryAttempts,
      config.retryDelay,
      signal
    );
  }

  /**
   * 批量视频生成
   */
  private async processVideoGenerate(
    item: BatchItem,
    signal: AbortSignal,
    config: BatchProcessingOptions
  ): Promise<string> {
    const { imageUrl, motionPrompt } = item.data;
    
    return await this.withRetry(
      () => aiService.generateVideo(imageUrl, motionPrompt, {}, (progress) => {
        item.progress = progress;
      }),
      config.retryAttempts,
      config.retryDelay,
      signal
    );
  }

  /**
   * 重试机制
   */
  private async withRetry<T>(
    operation: () => Promise<T>,
    maxRetries: number,
    delay: number,
    signal: AbortSignal
  ): Promise<T> {
    for (let attempt = 0; attempt <= maxRetries; attempt++) {
      if (signal.aborted) {
        throw new Error('Operation cancelled');
      }

      try {
        return await operation();
      } catch (error) {
        if (attempt === maxRetries) {
          throw error;
        }

        // 等待重试延迟
        await new Promise(resolve => setTimeout(resolve, delay * Math.pow(2, attempt)));
      }
    }

    throw new Error('Max retries exceeded');
  }

  /**
   * 生成缩略图
   */
  private generateThumbnail(result: any, nodeType: NodeType): string | undefined {
    if (nodeType === 'imageGenerate' || nodeType === 'imageEdit') {
      return typeof result === 'string' ? result : undefined;
    }
    if (nodeType === 'videoGenerate') {
      // 为视频生成缩略图
      return `https://picsum.photos/200/150?random=${Date.now()}`;
    }
    return undefined;
  }

  /**
   * 取消批量处理
   */
  cancelBatch(): void {
    // 取消所有活动的处理
    for (const controller of this.activeProcesses.values()) {
      controller.abort();
    }
    this.activeProcesses.clear();

    // 清空队列
    this.processingQueue = [];
  }

  /**
   * 获取处理统计
   */
  getStats(): {
    total: number;
    completed: number;
    failed: number;
    pending: number;
    processing: number;
  } {
    return {
      total: this.completedItems.length + this.failedItems.length + this.processingQueue.length + this.activeProcesses.size,
      completed: this.completedItems.length,
      failed: this.failedItems.length,
      pending: this.processingQueue.length,
      processing: this.activeProcesses.size
    };
  }
}

// 创建全局批量处理器实例
export const batchProcessor = new BatchProcessor();
