import { notification } from 'antd';
import { downloadVideo } from './tools';
import { getGenerateEditPlan } from '@/api/video_flow';

/**
 * 导出服务 - 封装视频导出相关功能
 * 支持流式导出、进度轮询、失败重试机制
 */

// 导出请求接口
interface ExportRequest {
  project_id: string;
  ir: IRData;
  options: ExportOptions;
}

// IR数据结构
interface IRData {
  width: number;
  height: number;
  fps: number;
  duration: number;
  video: VideoElement[];
  texts: TextElement[];
  audio: any[];
  transitions: TransitionElement[];
}

// 视频元素结构
interface VideoElement {
  id: string;
  src: string;
  start: number;
  end: number;
  in: number;
  out: number;
  _source_type: 'remote_url' | 'local';
}

// 文本元素结构
interface TextElement {
  id: string;
  text: string;
  start: number;
  end: number;
  style: {
    fontFamily: string;
    fontSize: number;
    color: string;
    backgroundColor: string;
    fontWeight: 'normal' | 'bold';
    fontStyle: 'normal' | 'italic';
    align: 'left' | 'center' | 'right';
    shadow: boolean;
  };
}

// 转场元素结构
interface TransitionElement {
  id: string;
  type: string;
  duration: number;
  start: number;
  end: number;
}

// 导出选项
interface ExportOptions {
  quality: 'preview' | 'standard' | 'professional';
  codec: string;
  subtitleMode: 'hard' | 'soft';
}

// 导出进度状态类型
type ExportStatus = 'processing' | 'completed' | 'failed';

// 导出进度回调接口
interface ExportProgressCallback {
  onProgress?: (data: {
    status: ExportStatus;
    percentage: number;
    message: string;
    stage?: string;
    taskId?: string;
  }) => void;
}

// 导出服务配置
interface ExportServiceConfig {
  maxRetries?: number;
  pollInterval?: number;
  apiBaseUrl?: string;
}

// 导出结果
interface ExportResult {
  task_id: string;
  status: string;
  video_url?: string;
  file_size?: number;
  export_id?: string;
  quality_mode?: string;
  watermark_status?: string;
  upload_time?: string;
}

/**
 * 视频导出服务类
 */
export class VideoExportService {
  private config: Required<ExportServiceConfig>;
  private cachedExportRequest: ExportRequest | null = null;

  constructor(config: ExportServiceConfig = {}) {
    this.config = {
      maxRetries: config.maxRetries || 3,
      pollInterval: config.pollInterval || 5000, // 5秒轮询
      apiBaseUrl: process.env.NEXT_PUBLIC_CUT_URL || 'https://smartcut.api.movieflow.ai'
    };
  }

  /**
   * 辅助函数：将时间码转换为毫秒
   */
  private parseTimecodeToMs(timecode: string): number {
    // 处理两种时间码格式:
    // 1. "00:00:08.000" (时:分:秒.毫秒) - 剪辑计划格式
    // 2. "00:00:08:00" (时:分:秒:帧) - 传统时间码格式
    
    if (timecode.includes('.')) {
      // 格式: "00:00:08.000"
      const [timePart, msPart] = timecode.split('.');
      const [hours, minutes, seconds] = timePart.split(':').map(Number);
      const milliseconds = parseInt(msPart.padEnd(3, '0').slice(0, 3));
      
      return (hours * 3600 + minutes * 60 + seconds) * 1000 + milliseconds;
    } else {
      // 格式: "00:00:08:00" (时:分:秒:帧)
      const parts = timecode.split(':');
      if (parts.length !== 4) return 0;

      const hours = parseInt(parts[0]) || 0;
      const minutes = parseInt(parts[1]) || 0;
      const seconds = parseInt(parts[2]) || 0;
      const frames = parseInt(parts[3]) || 0;

      // 假设30fps
      const totalSeconds = hours * 3600 + minutes * 60 + seconds + frames / 30;
      return Math.round(totalSeconds * 1000);
    }
  }

  /**
   * 获取剪辑计划（带重试机制）
   * 8秒重试一次，最长重试10分钟，直到成功
   */
  private async getEditingPlanWithRetry(episodeId: string, progressCallback?: ExportProgressCallback['onProgress']): Promise<any> {
    const maxRetryTime = 10 * 60 * 1000; // 10分钟
    const retryInterval = 8 * 1000; // 8秒
    const maxAttempts = Math.floor(maxRetryTime / retryInterval); // 75次
    
    console.log('🎬 开始获取剪辑计划（带重试机制）...');
    console.log(`⏰ 重试配置: ${retryInterval/1000}秒间隔，最多${maxAttempts}次，总时长${maxRetryTime/1000/60}分钟`);
    
    let attempts = 0;
    
    while (attempts < maxAttempts) {
      attempts++;
      
      try {
        console.log(`🔄 第${attempts}次尝试获取剪辑计划...`);
        
        // 触发进度回调
        if (progressCallback) {
          // 剪辑计划获取占总进度的80%，因为可能需要很长时间
          const progressPercent = Math.min(Math.round((attempts / maxAttempts) * 80), 75);
          progressCallback({
            status: 'processing',
            percentage: progressPercent,
            message: `正在获取剪辑计划... (第${attempts}次尝试，预计${Math.ceil((maxAttempts - attempts) * retryInterval / 1000 / 60)}分钟)`,
            stage: 'fetching_editing_plan'
          });
        }
        
        const editPlanResponse = await getGenerateEditPlan({ project_id: episodeId });
        
        if (editPlanResponse.successful && editPlanResponse.data.editing_plan) {
          console.log(`✅ 第${attempts}次尝试成功获取剪辑计划`);
          return editPlanResponse.data.editing_plan;
        } else {
          console.log(`⚠️ 第${attempts}次尝试失败: ${editPlanResponse.message || '剪辑计划未生成'}`);
          
          if (attempts >= maxAttempts) {
            throw new Error(`获取剪辑计划失败，已重试${maxAttempts}次: ${editPlanResponse.message}`);
          }
          
          console.log(`⏳ ${retryInterval/1000}秒后进行第${attempts + 1}次重试...`);
          await new Promise(resolve => setTimeout(resolve, retryInterval));
        }
      } catch (error) {
        console.log(`❌ 第${attempts}次尝试出现错误:`, error);
        
        if (attempts >= maxAttempts) {
          throw new Error(`获取剪辑计划失败，已重试${maxAttempts}次: ${error instanceof Error ? error.message : '未知错误'}`);
        }
        
        console.log(`⏳ ${retryInterval/1000}秒后进行第${attempts + 1}次重试...`);
        await new Promise(resolve => setTimeout(resolve, retryInterval));
      }
    }
    
    throw new Error(`获取剪辑计划超时，已重试${maxAttempts}次`);
  }

  /**
   * 基于剪辑计划生成导出数据
   */
  private async generateExportDataFromEditingPlan(
    episodeId: string, 
    taskObject: any, 
    progressCallback?: ExportProgressCallback['onProgress']
  ): Promise<{
    exportRequest: ExportRequest;
    editingPlan: any;
  }> {
    try {
      // 1. 首先获取剪辑计划（带重试机制）
      const editingPlan = await this.getEditingPlanWithRetry(episodeId, progressCallback);
      console.log('📋 最终获取到剪辑计划:', editingPlan);

      // 2. 检查是否有可用的视频数据
      if (!taskObject.videos?.data || taskObject.videos.data.length === 0) {
        throw new Error('没有可用的视频数据');
      }

      // 3. 过滤出已完成的视频
      const completedVideos = taskObject.videos.data.filter((video: any) =>
        video.video_status === 1 && video.urls && video.urls.length > 0
      );

      if (completedVideos.length === 0) {
        throw new Error('没有已完成的视频片段');
      }

      console.log(`📊 找到 ${completedVideos.length} 个已完成的视频片段`);

      // 4. 根据剪辑计划转换视频数据 - 符合API文档的VideoElement格式
      const defaultClipDuration = 8000; // 默认8秒每个片段（毫秒）
      let currentStartTime = 0; // 当前时间轴位置

      // 构建视频元素数组 - 严格按照API文档的VideoElement结构
      let videoElements: VideoElement[];

      if (editingPlan.editing_sequence_plans && editingPlan.editing_sequence_plans.length > 0) {
        // 使用剪辑计划中的时间线信息
        const timelineClips = editingPlan.editing_sequence_plans[0].timeline_clips || [];
        console.log('🎞️ 使用剪辑计划中的时间线信息:', timelineClips);

        videoElements = timelineClips.map((clip: any, index: number) => {
          // 查找对应的视频数据
          const matchedVideo = completedVideos.find((video: any) =>
            video.video_id === clip.source_clip_id ||
            video.urls?.some((url: string) => url === clip.video_url)
          );

          // 优先使用剪辑计划中的video_url，其次使用匹配视频的URL
          const videoUrl = clip.video_url || matchedVideo?.urls?.[0];
          
          // 解析剪辑计划中的精确时间码
          const sequenceStartMs = this.parseTimecodeToMs(clip.sequence_start_timecode || "00:00:00.000");
          const sourceInMs = this.parseTimecodeToMs(clip.source_in_timecode || "00:00:00.000");
          const sourceOutMs = this.parseTimecodeToMs(clip.source_out_timecode || "00:00:08.000");
          const clipDurationMs = this.parseTimecodeToMs(clip.clip_duration_in_sequence || "00:00:08.000");

          console.log(`🎬 处理片段 ${clip.sequence_clip_id}:`, {
            video_url: videoUrl,
            sequence_start: sequenceStartMs,
            source_in: sourceInMs,
            source_out: sourceOutMs,
            duration: clipDurationMs
          });

          // 严格按照API文档的VideoElement结构
          const element: VideoElement = {
            id: clip.sequence_clip_id || matchedVideo?.video_id || `video_${index + 1}`,
            src: videoUrl,
            start: currentStartTime, // 在时间轴上的开始时间
            end: currentStartTime + clipDurationMs, // 在时间轴上的结束时间
            in: sourceInMs,  // 视频内部开始时间
            out: sourceOutMs, // 视频内部结束时间
            _source_type: videoUrl?.startsWith('http') ? 'remote_url' : 'local'
          };

          currentStartTime += clipDurationMs;
          return element;
        });
      } else {
        // 如果没有具体的时间线信息，使用视频数据生成
        console.log('📹 使用视频数据生成时间线');
        videoElements = completedVideos.map((video: any, index: number) => {
          const videoUrl = video.urls![0];
          
          // 严格按照API文档的VideoElement结构
          const element: VideoElement = {
            id: video.video_id || `video_${index + 1}`,
            src: videoUrl,
            start: currentStartTime,
            end: currentStartTime + defaultClipDuration, // 添加end字段
            in: 0,
            out: defaultClipDuration,
            _source_type: videoUrl.startsWith('http') ? 'remote_url' : 'local'
          };

          currentStartTime += defaultClipDuration;
          return element;
        });
      }

      const totalDuration = currentStartTime;

      // 处理转场效果
      const transitions: TransitionElement[] = [];
      if (editingPlan.editing_sequence_plans?.[0]?.timeline_clips) {
        const timelineClips = editingPlan.editing_sequence_plans[0].timeline_clips;
        
        for (let i = 0; i < timelineClips.length; i++) {
          const clip = timelineClips[i];
          if (clip.transition_from_previous && i > 0) {
            const transition: TransitionElement = {
              id: `transition_${i}`,
              type: clip.transition_from_previous.transition_type || 'Cut',
              duration: clip.transition_from_previous.transition_duration_ms || 0,
              start: this.parseTimecodeToMs(clip.sequence_start_timecode || "00:00:00.000") - (clip.transition_from_previous.transition_duration_ms || 0),
              end: this.parseTimecodeToMs(clip.sequence_start_timecode || "00:00:00.000")
            };
            transitions.push(transition);
          }
        }
      }

      // 处理字幕/对话轨道
      const texts: TextElement[] = [];
      if (editingPlan.finalized_dialogue_track?.final_dialogue_segments) {
        editingPlan.finalized_dialogue_track.final_dialogue_segments.forEach((dialogue: any, index: number) => {
          const textElement: TextElement = {
            id: dialogue.sequence_clip_id || `text_${index + 1}`,
            text: dialogue.transcript,
            start: this.parseTimecodeToMs(dialogue.start_timecode || "00:00:00.000"),
            end: this.parseTimecodeToMs(dialogue.end_timecode || "00:00:02.000"),
            style: {
              fontFamily: 'Arial',
              fontSize: 40,
              color: '#FFFFFF',
              backgroundColor: 'transparent',
              fontWeight: 'normal',
              fontStyle: 'normal',
              align: 'center',
              shadow: true
            }
          };
          texts.push(textElement);
        });
      }

      // 构建符合API文档的IR数据结构
      const irData: IRData = {
        width: 1920,
        height: 1080,
        fps: 30,
        duration: totalDuration,
        video: videoElements,
        texts: texts, // 从剪辑计划中提取的字幕
        audio: [], // 可选字段，空数组
        transitions: transitions // 从剪辑计划中提取的转场
      };

      // 构建完整的导出请求数据 - 符合API文档的ExportRequest格式
      const exportRequest: ExportRequest = {
        project_id: episodeId,
        ir: irData,
        options: {
          quality: 'standard',
          codec: 'h264',
          subtitleMode: 'hard'
        }
      };

      return {
        exportRequest,
        editingPlan: editingPlan // 保存剪辑计划信息用于调试
      };

    } catch (error) {
      console.error('❌ 生成导出数据失败:', error);
      throw error;
    }
  }

  /**
   * 调用导出流接口的核心函数
   */
  private async callExportStreamAPI(exportRequest: ExportRequest, attemptNumber: number = 1): Promise<any> {
    console.log(`🚀 第${attemptNumber}次调用流式导出接口...`);
    console.log('📋 发送的完整导出请求数据:', JSON.stringify(exportRequest, null, 2));

    const response = await fetch(`${this.config.apiBaseUrl}/api/export/stream`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'text/event-stream'
      },
      body: JSON.stringify(exportRequest)
    });

    console.log('📡 导出接口响应状态:', response.status, response.statusText);
    console.log('📋 响应头信息:', Object.fromEntries(response.headers.entries()));

    if (!response.ok) {
      const errorText = await response.text();
      console.error('❌ 导出接口错误响应:', errorText);
      throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`);
    }

    console.log('✅ 导出接口调用成功，开始处理SSE流...');

    // 处理SSE流式响应
    console.log('📺 开始处理流式响应...');
    const reader = response.body?.getReader();
    const decoder = new TextDecoder();
    let eventCount = 0;
    let finalResult = null;
    let detectedTaskId = null; // 用于收集任务ID

    if (reader) {
      try {
        while (true) {
          const { done, value } = await reader.read();
          if (done) break;

          const chunk = decoder.decode(value);
          const lines = chunk.split('\n');

          for (const line of lines) {
            if (line.startsWith('data: ')) {
              try {
                const eventData = JSON.parse(line.slice(6));
                eventCount++;
                console.log(`📨 SSE事件 #${eventCount}:`, eventData);

                // 尝试从任何事件中提取任务ID
                if (eventData.export_id || eventData.task_id) {
                  detectedTaskId = eventData.export_id || eventData.task_id;
                  console.log('🔍 在SSE事件中发现任务ID:', detectedTaskId);
                }

                // 处理不同类型的事件，按照API文档规范
                switch (eventData.type) {
                  case 'start':
                    console.log('🚀 导出开始:', eventData.message);
                    // start事件中可能包含任务ID
                    if (eventData.export_id || eventData.task_id) {
                      detectedTaskId = eventData.export_id || eventData.task_id;
                      console.log('📋 从start事件获取任务ID:', detectedTaskId);
                    }
                    break;
                  
                  case 'progress':
                    const progressPercent = Math.round((eventData.progress || 0) * 100);
                    console.log(`📊 导出进度: ${progressPercent}% - ${eventData.stage || 'processing'} - ${eventData.message}`);
                    break;
                  
                  case 'complete':
                    console.log('🎉 导出完成！完整事件数据:', JSON.stringify(eventData, null, 2));
                    finalResult = eventData;
                    // 确保最终结果包含任务ID
                    if (detectedTaskId && !finalResult.export_id && !finalResult.task_id) {
                      finalResult.export_id = detectedTaskId;
                      console.log('📋 添加检测到的任务ID到完成结果:', detectedTaskId);
                    }
                    console.log('✅ 最终SSE结果:', JSON.stringify(finalResult, null, 2));
                    // 导出完成，退出循环
                    return finalResult;
                  
                  case 'error':
                    throw new Error(`导出失败: ${eventData.message}`);
                  
                  default:
                    console.log('📋 其他事件:', eventData);
                }
              } catch (parseError) {
                console.warn('⚠️ 解析SSE事件失败:', line, parseError);
              }
            }
          }
        }
      } finally {
        reader.releaseLock();
      }
    }

    // 如果有检测到的任务ID，确保添加到最终结果中
    if (detectedTaskId && finalResult && !finalResult.export_id && !finalResult.task_id) {
      finalResult.export_id = detectedTaskId;
      console.log('📋 将检测到的任务ID添加到最终结果:', detectedTaskId);
    }

    return finalResult;
  }

  /**
   * 轮询导出进度的函数
   * - status: 'completed' 时立即停止轮询并返回结果
   * - status: 'failed' 时抛出 EXPORT_FAILED 错误，触发重新调用 api/export/stream
   * - 其他状态继续轮询，最多轮询10分钟（5秒间隔）
   */
  private async pollExportProgress(taskId: string, progressCallback?: ExportProgressCallback['onProgress']): Promise<ExportResult> {
    console.log('🔄 开始轮询导出进度，任务ID:', taskId);
    const maxAttempts = 120; // 最多轮询10分钟（5秒间隔）
    let attempts = 0;

    while (attempts < maxAttempts) {
      try {
        const progressUrl = `${this.config.apiBaseUrl}/api/export/task/${taskId}/progress`;
        console.log(`📊 第${attempts + 1}次查询进度:`, progressUrl);

        const response = await fetch(progressUrl);
        
        if (!response.ok) {
          throw new Error(`进度查询失败: ${response.status} ${response.statusText}`);
        }

        const progressData = await response.json();
        console.log('📈 进度查询响应状态:', response.status, response.statusText);
        console.log('📊 完整进度数据:', JSON.stringify(progressData, null, 2));

        // 根据API返回的数据结构处理
        const { status, progress } = progressData;
        
        if (status === 'completed') {
          console.log('🎉 导出任务完成！progress数据:', JSON.stringify(progress, null, 2));
          
          // 触发完成状态回调
          if (progressCallback) {
            progressCallback({
              status: 'completed',
              percentage: 100,
              message: progress?.message || '导出完成',
              stage: 'completed',
              taskId
            });
          }
          
          const completedResult = {
            task_id: taskId,
            status: status,
            video_url: progress?.video_url,
            file_size: progress?.file_size,
            export_id: progress?.export_id,
            quality_mode: progress?.quality_mode,
            watermark_status: progress?.watermark_status,
            upload_time: progress?.upload_time
          };
          
          console.log('✅ 轮询返回的完成结果:', JSON.stringify(completedResult, null, 2));
          return completedResult;
        } else if (status === 'failed') {
          console.log('❌ 导出任务失败，需要重新调用 api/export/stream');
          
          // 触发失败状态回调
          if (progressCallback) {
            progressCallback({
              status: 'failed',
              percentage: 0,
              message: progress?.message || '导出任务失败',
              stage: 'failed',
              taskId
            });
          }
          
          throw new Error(`EXPORT_FAILED: ${progress?.message || '导出任务失败'}`);
        } else if (status === 'error') {
          throw new Error(`导出任务错误: ${progress?.message || '未知错误'}`);
        } else {
          // 任务仍在进行中
          const percentage = progress?.percentage || 0;
          const message = progress?.message || '处理中...';
          const stage = progress?.stage || 'processing';
          
          console.log(`⏳ 导出进度: ${percentage}% - ${stage} - ${message}`);
          
          // 触发处理中状态回调
          if (progressCallback) {
            progressCallback({
              status: 'processing',
              percentage,
              message,
              stage,
              taskId
            });
          }
          
          // 等待5秒后继续轮询
          await new Promise(resolve => setTimeout(resolve, this.config.pollInterval));
          attempts++;
        }
      } catch (error) {
        console.error(`❌ 第${attempts + 1}次进度查询失败:`, error);
        attempts++;
        
        // 如果不是最后一次尝试，等待5秒后重试
        if (attempts < maxAttempts) {
          await new Promise(resolve => setTimeout(resolve, this.config.pollInterval));
        }
      }
    }

    throw new Error('导出进度查询超时，请稍后手动检查');
  }

  /**
   * 主要的导出方法 - 支持重试机制
   */
  public async exportVideo(episodeId: string, taskObject: any, progressCallback?: ExportProgressCallback['onProgress']): Promise<ExportResult> {
    let currentAttempt = 1;

    try {
      // 重试循环
      while (currentAttempt <= this.config.maxRetries) {
        try {
          // 第一步：获取剪辑计划（只在第一次尝试时获取，或缓存不存在时重新获取）
          let exportRequest: ExportRequest;
          if (currentAttempt === 1 || !this.cachedExportRequest) {
            console.log('🎬 步骤1: 获取剪辑计划...');
            try {
              const { exportRequest: generatedExportRequest, editingPlan: generatedEditingPlan } = await this.generateExportDataFromEditingPlan(episodeId, taskObject, progressCallback);
              exportRequest = generatedExportRequest;

              console.log('📤 生成的导出请求数据:', exportRequest);
              console.log(`📊 包含 ${exportRequest.ir.video.length} 个视频片段，总时长: ${exportRequest.ir.duration}ms`);
              console.log('🎬 使用的剪辑计划:', generatedEditingPlan);

              // 缓存exportRequest以便重试时使用
              this.cachedExportRequest = exportRequest;
            } catch (editPlanError) {
              console.error('❌ 获取剪辑计划失败，无法继续导出:', editPlanError);
              // 剪辑计划获取失败是致命错误，直接抛出，不进行导出重试
              throw editPlanError;
            }
          } else {
            // 重试时使用缓存的请求数据
            exportRequest = this.cachedExportRequest;
            console.log(`🔄 第${currentAttempt}次重试，使用缓存的导出请求数据`);
          }

          // 第二步：调用导出接口
          console.log(`🚀 步骤2: 第${currentAttempt}次调用流式导出接口...`);
          const result = await this.callExportStreamAPI(exportRequest, currentAttempt);

          console.log('✅ 导出接口调用成功');
          console.log('🔍 SSE最终结果详情:', JSON.stringify(result, null, 2));

          // 尝试获取任务ID进行轮询
          let taskId = null;
          
          // 方法1: 从SSE结果中获取
          if (result?.export_id || result?.task_id) {
            taskId = result.export_id || result.task_id;
            console.log('📋 从SSE结果中获取到任务ID:', taskId);
          }

          // 如果没有任务ID，无法进行轮询
          if (!taskId) {
            console.log('⚠️ SSE结果中未找到任务ID，无法进行进度轮询');
            
            // 显示警告通知 - 已注释
            /*
            notification.warning({
              message: `第${currentAttempt}次导出接口调用成功`,
              description: 'SSE流中未找到任务ID，无法进行进度轮询。请检查API返回数据结构。',
              placement: 'topRight',
              duration: 8
            });
            */

            // 如果SSE中直接有完整结果，直接处理
            if (result?.download_url || result?.video_url) {
              const downloadUrl = result.download_url || result.video_url;
              console.log('📥 直接从SSE结果获取视频URL:', downloadUrl);

              // 🚫 暂时不支持自动下载 - 已注释
              // await downloadVideo(downloadUrl);

              // notification.success({
              //   message: '视频下载完成！',
              //   description: result?.file_size
              //     ? `文件大小: ${(result.file_size / 1024 / 1024).toFixed(2)}MB`
              //     : '视频已成功下载到本地',
              //   placement: 'topRight',
              //   duration: 8
              // });
            }

            return result;
          }

          // 如果有任务ID，开始轮询进度
          console.log('🔄 开始轮询导出进度，任务ID:', taskId);
          
          try {
            const finalExportResult = await this.pollExportProgress(taskId, progressCallback);
            
            // 导出成功
            console.log('🎉 导出成功完成！');
            console.log('📋 轮询最终结果:', JSON.stringify(finalExportResult, null, 2));
            
            // 显示最终成功通知 - 已注释
            /*
            notification.success({
              message: `导出成功！(第${currentAttempt}次尝试)`,
              description: `文件大小: ${(finalExportResult.file_size! / 1024 / 1024).toFixed(2)}MB，正在下载到本地...`,
              placement: 'topRight',
              duration: 8
            });
            */

            // 🚫 暂时不支持自动下载 - 已注释
            if (finalExportResult.video_url) {
              console.log('📥 视频导出完成，URL:', finalExportResult.video_url);
              console.log('📋 视频文件信息:', {
                url: finalExportResult.video_url,
                file_size: finalExportResult.file_size,
                quality_mode: finalExportResult.quality_mode
              });
              // await downloadVideo(finalExportResult.video_url);
              console.log('✅ 视频导出完成，用户可手动下载');
            }

            // 清除缓存的请求数据
            this.cachedExportRequest = null;
            
            return finalExportResult;

          } catch (pollError) {
            console.error(`❌ 第${currentAttempt}次轮询进度失败:`, pollError);
            
            // 检查是否是导出失败错误（需要重新调用 api/export/stream）
            const isExportFailed = pollError instanceof Error && pollError.message.startsWith('EXPORT_FAILED:');
            
            if (isExportFailed) {
              console.log(`❌ 第${currentAttempt}次导出任务失败（status: 'failed'），需要重新调用 api/export/stream`);
              
              // 如果还有重试次数，继续重试
              if (currentAttempt < this.config.maxRetries) {
                console.log(`🔄 准备第${currentAttempt + 1}次重试（重新调用 api/export/stream）...`);
                
                // notification.warning({
                //   message: `第${currentAttempt}次导出失败`,
                //   description: `导出状态: failed。正在准备第${currentAttempt + 1}次重试...`,
                //   placement: 'topRight',
                //   duration: 5
                // });

                currentAttempt++;
                continue; // 继续重试循环，重新调用 api/export/stream
              } else {
                // 已达到最大重试次数
                throw new Error(`导出失败，已重试${this.config.maxRetries}次。最后状态: failed`);
              }
            } else {
              // 其他轮询错误（网络错误等）
              if (currentAttempt < this.config.maxRetries) {
                console.log(`🔄 轮询失败，准备第${currentAttempt + 1}次重试...`);
                
                // notification.warning({
                //   message: `第${currentAttempt}次轮询失败`,
                //   description: `${pollError instanceof Error ? pollError.message : '未知错误'}。正在准备第${currentAttempt + 1}次重试...`,
                //   placement: 'topRight',
                //   duration: 5
                // });

                currentAttempt++;
                continue; // 继续重试循环
              } else {
                // 已达到最大重试次数，回退到SSE结果
                console.log('❌ 已达到最大重试次数，回退到SSE结果');
                
                // notification.error({
                //   message: '轮询重试失败',
                //   description: `已重试${this.config.maxRetries}次仍然失败。${pollError instanceof Error ? pollError.message : '未知错误'}`,
                //   placement: 'topRight',
                //   duration: 10
                // });

                // 回退到SSE结果
                if (result?.download_url || result?.video_url) {
                  const downloadUrl = result.download_url || result.video_url;
                  console.log('📥 回退到SSE结果下载视频:', downloadUrl);
                  await downloadVideo(downloadUrl);
                }

                // 清除缓存的请求数据
                this.cachedExportRequest = null;
                
                throw pollError;
              }
            }
          }

        } catch (attemptError) {
          console.error(`❌ 第${currentAttempt}次尝试失败:`, attemptError);
          
          // 如果还有重试次数，继续重试
          if (currentAttempt < this.config.maxRetries) {
            console.log(`🔄 第${currentAttempt}次尝试失败，准备第${currentAttempt + 1}次重试...`);
            
            // notification.warning({
            //   message: `第${currentAttempt}次导出尝试失败`,
            //   description: `${attemptError instanceof Error ? attemptError.message : '未知错误'}。正在准备第${currentAttempt + 1}次重试...`,
            //   placement: 'topRight',
            //   duration: 5
            // });

            currentAttempt++;
            continue; // 继续重试循环
          } else {
            // 已达到最大重试次数
            throw attemptError;
          }
        }
      }

      // 如果退出循环还没有成功，抛出错误
      throw new Error(`导出失败，已重试${this.config.maxRetries}次`);

    } catch (error) {
      console.error('❌ 视频导出最终失败:', error);

      // 清除缓存的请求数据
      this.cachedExportRequest = null;

      // 显示最终错误通知 - 已注释
      /*
      notification.error({
        message: '视频导出失败',
        description: `经过${this.config.maxRetries}次尝试后仍然失败：${error instanceof Error ? error.message : '未知错误'}`,
        placement: 'topRight',
        duration: 10
      });
      */

      throw error;
    }
  }
}

// 创建默认的导出服务实例
export const videoExportService = new VideoExportService({
  maxRetries: 3,
  pollInterval: 5000, // 5秒轮询间隔
  // apiBaseUrl 使用环境变量 NEXT_PUBLIC_CUT_URL，在构造函数中处理
});

/**
 * 便捷的导出函数
 */
export async function exportVideoWithRetry(
  episodeId: string, 
  taskObject: any, 
  progressCallback?: ExportProgressCallback['onProgress']
): Promise<ExportResult> {
  return videoExportService.exportVideo(episodeId, taskObject, progressCallback);
}

/**
 * 测试轮询逻辑的函数（开发调试用）
 */
export async function testPollingLogic(taskId: string): Promise<ExportResult> {
  console.log('🧪 测试轮询逻辑，任务ID:', taskId);
  return videoExportService['pollExportProgress'](taskId);
}
