/**
 * BowongTextVideoAgent FastAPI 服务
 * 基于 Tauri 桌面应用开发标准的完整服务实现
 * 版本: 1.0.6
 */

import { invoke } from '@tauri-apps/api/core';
import {
  BowongTextVideoAgentAPI,
  BowongTextVideoAgentConfig,
  BowongTextVideoAgentError,
  NetworkError,
  ValidationError,
  TaskTimeoutError,
  TaskFailedError,
  // 基础类型
  ApiResponse,
  FileUploadResponse,
  TaskStatus,
  TaskResponse,
  TaskStatusResponse,
  // 提示词预处理
  GetSamplePromptParams,
  SamplePromptResponse,
  // 文件操作
  FileUploadRequest,
  S3FileUploadRequest,
  // 视频模板管理
  GetTemplatesParams,
  TemplateListResponse,
  CheckTaskTypeParams,
  VideoTemplate,
  CreateTemplateRequest,
  UpdateTemplateRequest,
  // Midjourney 图片生成
  PromptCheckParams,
  SyncImageGenerationRequest,
  AsyncImageGenerationRequest,
  ImageDescribeRequest,
  ImageGenerationResponse,
  // 极梦视频生成
  VideoGenerationRequest,
  VideoGenerationResponse,
  VideoTaskStatus,
  BatchVideoStatusResponse,
  // 任务管理
  TaskRequest,
  // 302AI 服务集成
  AI302MJImageRequest,
  AI302TaskCancelRequest,
  AI302TaskStatusParams,
  AI302JMVideoRequest,
  AI302VEOVideoRequest,
  AI302VEOTaskStatusParams,
  // 海螺API
  SpeechGenerationRequest,
  VoiceListResponse,
  AudioFileUploadRequest,
  VoiceCloneRequest,
  // 聚合接口
  ModelListResponse,
  UnionImageGenerationRequest,
  UnionVideoGenerationRequest,
  // ComfyUI 工作流
  GetRunningNodeParams,
  ComfyUITaskRequest,
  ComfyUITaskStatusParams,
  ComfyUISyncExecuteRequest,
  // Hedra 口型合成
  HedraFileUploadRequest,
  HedraTaskSubmitRequest,
  HedraTaskStatusParams,
  // FFMPEG 任务
  BaseFFMPEGTaskStatusResponse,
  FFMPEGSliceRequest,
  ModalTaskResponse,
} from '../types/bowongTextVideoAgent';

/**
 * BowongTextVideoAgent FastAPI 服务类
 * 
 * 设计原则：
 * 1. 安全优先：所有API调用都经过验证和错误处理
 * 2. 性能优先：支持异步操作和任务轮询
 * 3. 跨平台一致性：基于Tauri invoke模式
 * 4. 模块化架构：按功能模块组织接口
 * 5. 类型安全：完整的TypeScript类型支持
 */
export class BowongTextVideoAgentFastApiService implements BowongTextVideoAgentAPI {
  private config: BowongTextVideoAgentConfig;
  private defaultTimeout = 30000; // 30秒
  private defaultRetryAttempts = 3;
  private defaultRetryDelay = 1000; // 1秒

  constructor(config: BowongTextVideoAgentConfig) {
    this.config = {
      timeout: this.defaultTimeout,
      retryAttempts: this.defaultRetryAttempts,
      retryDelay: this.defaultRetryDelay,
      ...config,
    };
  }

  /**
   * 通用API调用方法
   * 包含错误处理、重试机制和超时控制
   */
  private async invokeAPI<T>(
    command: string,
    params?: any,
    options?: {
      timeout?: number;
      retryAttempts?: number;
      retryDelay?: number;
    }
  ): Promise<T> {
    const timeout = options?.timeout || this.config.timeout || this.defaultTimeout;
    const retryAttempts = options?.retryAttempts || this.config.retryAttempts || this.defaultRetryAttempts;
    const retryDelay = options?.retryDelay || this.config.retryDelay || this.defaultRetryDelay;

    let lastError: Error;

    for (let attempt = 1; attempt <= retryAttempts; attempt++) {
      try {
        // 创建超时Promise
        const timeoutPromise = new Promise<never>((_, reject) => {
          setTimeout(() => {
            reject(new TaskTimeoutError(`API调用超时: ${command}`));
          }, timeout);
        });

        // 执行API调用
        const apiPromise = invoke<T>(command, params ? { params } : undefined);

        // 竞争执行，返回最先完成的结果
        const result = await Promise.race([apiPromise, timeoutPromise]);
        
        return result;
      } catch (error: any) {
        lastError = error;
        
        // 记录错误日志
        console.error(`API调用失败 (尝试 ${attempt}/${retryAttempts}):`, {
          command,
          params,
          error: error.message,
        });

        // 如果是最后一次尝试，直接抛出错误
        if (attempt === retryAttempts) {
          break;
        }

        // 等待重试延迟
        await new Promise(resolve => setTimeout(resolve, retryDelay));
      }
    }

    // 处理不同类型的错误
    this.handleError(lastError!, command);
    throw lastError!; // 这行代码实际不会执行，因为handleError会抛出错误
  }

  /**
   * 错误处理方法
   * 将原始错误转换为具体的错误类型
   */
  private handleError(error: any, command: string): never {
    if (error instanceof TaskTimeoutError) {
      throw error;
    }

    // 网络错误
    if (error.message?.includes('网络') || error.message?.includes('连接')) {
      throw new NetworkError(`网络连接失败: ${command}`, error.statusCode);
    }

    // 验证错误
    if (error.statusCode === 422 || error.message?.includes('验证')) {
      throw new ValidationError(`参数验证失败: ${command}`, error.details);
    }

    // 任务失败错误
    if (error.message?.includes('任务失败')) {
      throw new TaskFailedError(`任务执行失败: ${command}`, error.taskId, error.details);
    }

    // 通用错误
    throw new BowongTextVideoAgentError(
      `API调用失败: ${command} - ${error.message}`,
      'API_ERROR',
      error.statusCode,
      error
    );
  }

  /**
   * 异步任务轮询方法
   * 用于等待长时间运行的任务完成
   */
  private async pollTaskStatus<T extends TaskStatusResponse>(
    taskId: string,
    statusChecker: (taskId: string) => Promise<T>,
    options?: {
      maxWaitTime?: number;
      pollInterval?: number;
      onProgress?: (status: T) => void;
    }
  ): Promise<T> {
    const maxWaitTime = options?.maxWaitTime || 300000; // 5分钟
    const pollInterval = options?.pollInterval || 2000; // 2秒
    const startTime = Date.now();

    while (Date.now() - startTime < maxWaitTime) {
      try {
        const status = await statusChecker(taskId);
        
        // 调用进度回调
        if (options?.onProgress) {
          options.onProgress(status);
        }

        // 检查任务状态
        if (status.status === TaskStatus.SUCCESS) {
          return status;
        }
        
        if (status.status === TaskStatus.FAILED) {
          throw new TaskFailedError(
            `任务失败: ${status.error || '未知错误'}`,
            taskId,
            status
          );
        }

        if (status.status === TaskStatus.CANCELLED) {
          throw new TaskFailedError(`任务已取消`, taskId, status);
        }

        // 等待下次轮询
        await new Promise(resolve => setTimeout(resolve, pollInterval));
      } catch (error) {
        if (error instanceof TaskFailedError) {
          throw error;
        }
        
        // 其他错误继续轮询
        console.warn(`轮询任务状态时出错: ${error}`);
        await new Promise(resolve => setTimeout(resolve, pollInterval));
      }
    }

    throw new TaskTimeoutError(`任务轮询超时`, taskId);
  }

  // ============================================================================
  // 提示词预处理模块
  // ============================================================================

  async getSamplePrompt(params?: GetSamplePromptParams): Promise<SamplePromptResponse> {
    return this.invokeAPI<SamplePromptResponse>('bowong_get_sample_prompt', params);
  }

  async checkPromptHealth(): Promise<ApiResponse> {
    return this.invokeAPI<ApiResponse>('bowong_health_check');
  }

  // ============================================================================
  // 文件操作模块
  // ============================================================================

  async uploadFile(request: FileUploadRequest): Promise<FileUploadResponse> {
    return this.invokeAPI<FileUploadResponse>('bowong_upload_file', request);
  }

  async uploadFileToS3(request: S3FileUploadRequest): Promise<FileUploadResponse> {
    return this.invokeAPI<FileUploadResponse>('bowong_upload_file_to_s3', request);
  }

  async checkFileHealth(): Promise<ApiResponse> {
    return this.invokeAPI<ApiResponse>('bowong_file_health_check');
  }

  // ============================================================================
  // 视频模板管理模块
  // ============================================================================

  async getTemplates(params?: GetTemplatesParams): Promise<TemplateListResponse> {
    return this.invokeAPI<TemplateListResponse>('bowong_get_templates', params);
  }

  async checkTaskType(params: CheckTaskTypeParams): Promise<ApiResponse> {
    return this.invokeAPI<ApiResponse>('bowong_check_task_type', params);
  }

  async createTemplate(request: CreateTemplateRequest): Promise<ApiResponse<VideoTemplate>> {
    const template = await this.invokeAPI<VideoTemplate>('bowong_create_template', request);
    return {
      status: true,
      msg: 'Template created successfully',
      data: template
    };
  }

  async updateTemplate(request: UpdateTemplateRequest): Promise<ApiResponse<VideoTemplate>> {
    const template = await this.invokeAPI<VideoTemplate>('bowong_update_template', request);
    return {
      status: true,
      msg: 'Template updated successfully',
      data: template
    };
  }

  async deleteTemplate(templateId: string): Promise<ApiResponse> {
    return this.invokeAPI<ApiResponse>('bowong_delete_template', { templateId });
  }

  // ============================================================================
  // Midjourney 图片生成模块
  // ============================================================================

  async checkPrompt(params: PromptCheckParams): Promise<ApiResponse> {
    return this.invokeAPI<ApiResponse>('bowong_check_prompt', params);
  }

  async syncGenerateImage(request: SyncImageGenerationRequest): Promise<ImageGenerationResponse> {
    const maxWaitTime = request.max_wait_time || 120000; // 2分钟
    const pollInterval = (request.poll_interval || 2) * 1000; // 转换为毫秒

    // 提交异步任务
    const taskResponse = await this.asyncGenerateImage({
      prompt: request.prompt,
      img_file: request.img_file,
    });

    // 轮询任务状态
    const finalStatus = await this.pollTaskStatus(
      taskResponse.data,
      (taskId) => this.queryImageTaskStatus(taskId),
      {
        maxWaitTime,
        pollInterval,
      }
    );

    return {
      task_id: finalStatus.task_id,
      status: finalStatus.status,
      images: finalStatus.result?.images,
      error: finalStatus.error,
    };
  }

  async asyncGenerateImage(request: AsyncImageGenerationRequest): Promise<TaskResponse> {
    return this.invokeAPI<TaskResponse>('bowong_async_generate_image', request);
  }

  async queryImageTaskStatus(taskId: string): Promise<TaskStatusResponse> {
    return this.invokeAPI<TaskStatusResponse>('bowong_get_task_status', taskId);
  }

  async describeImage(request: ImageDescribeRequest): Promise<ApiResponse> {
    return this.invokeAPI<ApiResponse>('bowong_describe_image', request);
  }

  // ============================================================================
  // 极梦视频生成模块
  // ============================================================================

  async generateVideo(request: VideoGenerationRequest): Promise<VideoGenerationResponse> {
    // 根据是否指定等待时间决定使用同步还是异步方式
    if (request.max_wait_time && request.max_wait_time > 0) {
      return this.syncGenerateVideo(request);
    } else {
      const taskResponse = await this.asyncGenerateVideo(request);
      return {
        task_id: taskResponse.data, // task_id is stored in the data field
        status: taskResponse.status ? TaskStatus.PENDING : TaskStatus.FAILED, // Convert boolean to TaskStatus
      };
    }
  }

  async syncGenerateVideo(request: VideoGenerationRequest): Promise<VideoGenerationResponse> {
    const maxWaitTime = request.max_wait_time || 300000; // 5分钟
    const pollInterval = (request.poll_interval || 5) * 1000; // 转换为毫秒

    // 提交异步任务
    const taskResponse = await this.asyncGenerateVideo(request);

    // 轮询任务状态
    const finalStatus = await this.pollTaskStatus(
      taskResponse.data,
      (taskId) => this.queryVideoTaskStatus(taskId),
      {
        maxWaitTime,
        pollInterval,
        onProgress: (status) => {
          console.log(`视频生成进度: ${status.progress || 0}%`);
        },
      }
    );

    return {
      task_id: finalStatus.task_id,
      status: finalStatus.status,
      video_url: finalStatus.result?.video_url,
      progress: finalStatus.progress,
      error: finalStatus.error,
    };
  }

  async asyncGenerateVideo(request: VideoGenerationRequest): Promise<TaskResponse> {
    return this.invokeAPI<TaskResponse>('bowong_generate_video', request);
  }

  async queryVideoTaskStatus(taskId: string): Promise<TaskStatusResponse> {
    return this.invokeAPI<TaskStatusResponse>('bowong_get_task_status', taskId);
  }

  async batchQueryVideoStatus(request: VideoTaskStatus): Promise<BatchVideoStatusResponse> {
    return this.invokeAPI<BatchVideoStatusResponse>('bowong_batch_query_video_status', request);
  }

  // ============================================================================
  // 任务管理模块
  // ============================================================================

  async createTask(request: TaskRequest): Promise<TaskResponse> {
    return this.invokeAPI<TaskResponse>('bowong_create_task', request);
  }

  async createTaskV2(request: TaskRequest): Promise<TaskResponse> {
    return this.invokeAPI<TaskResponse>('bowong_create_task', request);
  }

  async getTaskStatus(taskId: string): Promise<TaskStatusResponse> {
    return this.invokeAPI<TaskStatusResponse>('bowong_get_task_status', taskId);
  }

  // ============================================================================
  // 302AI 服务集成模块
  // ============================================================================

  async ai302MJAsyncGenerateImage(request: AI302MJImageRequest): Promise<TaskResponse> {
    return this.invokeAPI<TaskResponse>('bowong_ai302_mj_async_generate_image', request);
  }

  async ai302MJCancelTask(request: AI302TaskCancelRequest): Promise<ApiResponse> {
    return this.invokeAPI<ApiResponse>('bowong_ai302_mj_cancel_task', request);
  }

  async ai302MJQueryTaskStatus(params: AI302TaskStatusParams): Promise<TaskStatusResponse> {
    return this.invokeAPI<TaskStatusResponse>('bowong_ai302_mj_query_task_status', params);
  }

  async ai302MJDescribeImage(request: ImageDescribeRequest): Promise<ApiResponse> {
    return this.invokeAPI<ApiResponse>('bowong_describe_image', request);
  }

  async ai302MJSyncGenerateImage(request: SyncImageGenerationRequest): Promise<ImageGenerationResponse> {
    const maxWaitTime = request.max_wait_time || 120000;
    const pollInterval = (request.poll_interval || 2) * 1000;

    const taskResponse = await this.ai302MJAsyncGenerateImage({
      prompt: request.prompt,
      img_file: request.img_file,
    });

    const finalStatus = await this.pollTaskStatus(
      taskResponse.data,
      (taskId) => this.ai302MJQueryTaskStatus({ task_id: taskId }),
      { maxWaitTime, pollInterval }
    );

    return {
      task_id: finalStatus.task_id,
      status: finalStatus.status,
      images: finalStatus.result?.images,
      error: finalStatus.error,
    };
  }

  async ai302JMSyncGenerateVideo(request: AI302JMVideoRequest): Promise<VideoGenerationResponse> {
    const maxWaitTime = request.max_wait_time || 300000;
    const pollInterval = (request.poll_interval || 5) * 1000;

    const taskResponse = await this.ai302JMAsyncGenerateVideo(request);

    const finalStatus = await this.pollTaskStatus(
      taskResponse.data,
      (taskId) => this.ai302JMQueryVideoStatus(taskId),
      { maxWaitTime, pollInterval }
    );

    return {
      task_id: finalStatus.task_id,
      status: finalStatus.status,
      video_url: finalStatus.result?.video_url,
      progress: finalStatus.progress,
      error: finalStatus.error,
    };
  }

  async ai302JMAsyncGenerateVideo(request: AI302JMVideoRequest): Promise<TaskResponse> {
    return this.invokeAPI<TaskResponse>('bowong_ai302_jm_async_generate_video', request);
  }

  async ai302JMQueryVideoStatus(taskId: string): Promise<TaskStatusResponse> {
    return this.invokeAPI<TaskStatusResponse>('bowong_get_task_status', taskId);
  }

  async ai302VEOAsyncSubmit(request: AI302VEOVideoRequest): Promise<TaskResponse> {
    return this.invokeAPI<TaskResponse>('bowong_ai302_veo_async_submit', request);
  }

  async ai302VEOSyncGenerateVideo(request: AI302VEOVideoRequest): Promise<VideoGenerationResponse> {
    const maxWaitTime = request.max_wait_time || 500000; // 8分钟
    const pollInterval = (request.interval || 5) * 1000;

    const taskResponse = await this.ai302VEOAsyncSubmit(request);

    const finalStatus = await this.pollTaskStatus(
      taskResponse.data,
      (taskId) => this.ai302VEOGetTaskStatus({ task_id: taskId }),
      { maxWaitTime, pollInterval }
    );

    return {
      task_id: finalStatus.task_id,
      status: finalStatus.status,
      video_url: finalStatus.result?.video_url,
      error: finalStatus.error,
    };
  }

  async ai302VEOGetTaskStatus(params: AI302VEOTaskStatusParams): Promise<TaskStatusResponse> {
    return this.invokeAPI<TaskStatusResponse>('ai302_veo_get_task_status', params);
  }

  // ============================================================================
  // 海螺API模块
  // ============================================================================

  async generateSpeech(request: SpeechGenerationRequest): Promise<ApiResponse> {
    return this.invokeAPI<ApiResponse>('bowong_generate_speech', request);
  }

  async getVoices(): Promise<VoiceListResponse> {
    return this.invokeAPI<VoiceListResponse>('bowong_get_voices');
  }

  async uploadAudioFile(request: AudioFileUploadRequest): Promise<FileUploadResponse> {
    return this.invokeAPI<FileUploadResponse>('bowong_upload_audio_file', request);
  }

  async cloneVoice(request: VoiceCloneRequest): Promise<ApiResponse> {
    return this.invokeAPI<ApiResponse>('bowong_clone_voice', request);
  }

  // ============================================================================
  // 聚合接口模块
  // ============================================================================

  async getImageModelList(): Promise<ModelListResponse> {
    return this.invokeAPI<ModelListResponse>('bowong_get_image_model_list');
  }

  async unionSyncGenerateImage(request: UnionImageGenerationRequest): Promise<ImageGenerationResponse> {
    return this.invokeAPI<ImageGenerationResponse>('bowong_union_sync_generate_image', request);
  }

  async getVideoModelList(): Promise<ModelListResponse> {
    return this.invokeAPI<ModelListResponse>('bowong_get_video_model_list');
  }

  async unionAsyncGenerateVideo(request: UnionVideoGenerationRequest): Promise<TaskResponse> {
    return this.invokeAPI<TaskResponse>('bowong_union_async_generate_video', request);
  }

  async unionQueryVideoTaskStatus(taskId: string): Promise<TaskStatusResponse> {
    return this.invokeAPI<TaskStatusResponse>('bowong_get_task_status', taskId);
  }

  // ============================================================================
  // ComfyUI 工作流模块
  // ============================================================================

  async getRunningNode(params?: GetRunningNodeParams): Promise<ApiResponse> {
    return this.invokeAPI<ApiResponse>('bowong_get_running_node', params);
  }

  async submitComfyUITask(request: ComfyUITaskRequest): Promise<TaskResponse> {
    return this.invokeAPI<TaskResponse>('bowong_submit_comfyui_task', request);
  }

  async queryComfyUITaskStatus(params: ComfyUITaskStatusParams): Promise<TaskStatusResponse> {
    return this.invokeAPI<TaskStatusResponse>('bowong_query_comfyui_task_status', params);
  }

  async syncExecuteWorkflow(request: ComfyUISyncExecuteRequest): Promise<ApiResponse> {
    return this.invokeAPI<ApiResponse>('bowong_sync_execute_workflow', request);
  }

  // ============================================================================
  // Hedra 口型合成模块
  // ============================================================================

  async hedraUploadFile(request: HedraFileUploadRequest): Promise<FileUploadResponse> {
    return this.invokeAPI<FileUploadResponse>('hedra_upload_file', request);
  }

  async hedraSubmitTask(request: HedraTaskSubmitRequest): Promise<TaskResponse> {
    return this.invokeAPI<TaskResponse>('hedra_submit_task', request);
  }

  async hedraQueryTaskStatus(params: HedraTaskStatusParams): Promise<TaskStatusResponse> {
    return this.invokeAPI<TaskStatusResponse>('hedra_query_task_status', params);
  }

  // ============================================================================
  // FFMPEG 任务模块
  // ============================================================================

  async getFFMPEGTaskStatus(taskId: string): Promise<BaseFFMPEGTaskStatusResponse> {
    return this.invokeAPI<BaseFFMPEGTaskStatusResponse>('get_ffmpeg_task_status', { taskId });
  }

  async sliceMedia(request: FFMPEGSliceRequest): Promise<ModalTaskResponse> {
    return this.invokeAPI<ModalTaskResponse>('slice_media', request);
  }

  // ============================================================================
  // 工具方法
  // ============================================================================



  /**
   * 获取服务配置
   */
  getConfig(): BowongTextVideoAgentConfig {
    return { ...this.config };
  }

  /**
   * 更新服务配置
   */
  updateConfig(newConfig: Partial<BowongTextVideoAgentConfig>): void {
    this.config = { ...this.config, ...newConfig };
  }

  /**
   * 测试服务连接
   */
  async testConnection(): Promise<boolean> {
    try {
      await this.checkPromptHealth();
      await this.checkFileHealth();
      return true;
    } catch (error) {
      console.error('服务连接测试失败:', error);
      return false;
    }
  }

  /**
   * 批量取消任务
   */
  async cancelTasks(taskIds: string[]): Promise<ApiResponse[]> {
    const results: ApiResponse[] = [];

    for (const taskId of taskIds) {
      try {
        const result = await this.ai302MJCancelTask({ task_id: taskId });
        results.push(result);
      } catch (error) {
        console.error(`取消任务失败: ${taskId}`, error);
        results.push({
          status: false,
          msg: `取消任务失败: ${error}`,
        });
      }
    }

    return results;
  }

  /**
   * 批量查询任务状态
   */
  async batchQueryTaskStatus(taskIds: string[]): Promise<TaskStatusResponse[]> {
    const results: TaskStatusResponse[] = [];

    for (const taskId of taskIds) {
      try {
        const status = await this.getTaskStatus(taskId);
        results.push(status);
      } catch (error) {
        console.error(`查询任务状态失败: ${taskId}`, error);
        results.push({
          task_id: taskId,
          status: TaskStatus.FAILED,
          error: `查询失败: ${error}`,
        });
      }
    }

    return results;
  }
}

/**
 * 创建服务实例的工厂函数
 */
export function createBowongTextVideoAgentService(
  config: BowongTextVideoAgentConfig
): BowongTextVideoAgentFastApiService {
  return new BowongTextVideoAgentFastApiService(config);
}

/**
 * 默认服务实例（单例模式）
 */
let defaultServiceInstance: BowongTextVideoAgentFastApiService | null = null;

/**
 * 获取默认服务实例
 */
export function getDefaultBowongTextVideoAgentService(): BowongTextVideoAgentFastApiService {
  if (!defaultServiceInstance) {
    throw new BowongTextVideoAgentError(
      '默认服务实例未初始化，请先调用 initializeDefaultService',
      'SERVICE_NOT_INITIALIZED'
    );
  }
  return defaultServiceInstance;
}

/**
 * 初始化默认服务实例
 */
export function initializeDefaultService(config: BowongTextVideoAgentConfig): void {
  defaultServiceInstance = new BowongTextVideoAgentFastApiService(config);
}

/**
 * 重置默认服务实例
 */
export function resetDefaultService(): void {
  defaultServiceInstance = null;
}
