// 移除Taro依赖，使用Web标准API

/**
 * API 响应基础接口
 */
interface ApiResponse<T = any> {
  status: boolean | string;
  data: T;
  msg: string;
}

/**
 * 文件上传参数
 */
interface UploadParams {
  /** 文件路径或File对象 */
  filePath: string | File;
  /** 文件名，可选，默认会自动生成 */
  name?: string;
  /** 文件类型，可选，会根据文件扩展名自动判断 */
  type?: string;
  /** 上传进度回调 */
  onProgress?: (progress: number) => void;
}

/**
 * 图像生成请求参数
 */
interface GenerateImageParams {
  /** 生成提示词 */
  prompt: string;
  /** 模型名称，默认使用 gemini-2.5-flash-image-preview */
  model_name?: string;
  /** 图像宽高比，如 '9:16', '16:9', '1:1' 等，默认为 '9:16' */
  aspect_ratio?: string;
  /** 生成模式，默认为 turbo */
  mode?: 'turbo' | 'standard';
  /** 是否启用 webhook 回调，默认为 false */
  webhook_flag?: boolean;
  img_file: string | File;
}

/**
 * 图像转视频请求参数
 */
interface ImageToVideoParams {
  /** 图像URL地址 */
  img_url: string;
  /** 视频时长，默认为0 */
  duration?: number;
}

// H5版本不需要这个类型检查函数
// export function isGetFileInfoSuccessCallbackResult(val: any): val is Taro.getFileInfo.SuccessCallbackResult {
//   return val && Reflect.has(val, 'digest')
// }

/**
 * BowongAI SDK 类
 * 提供图像生成等 AI 功能的接口封装
 */
export class BowongAISDK {
  /** API 服务基础地址 */
  private readonly baseUrl = 'https://bowongai-test--text-video-agent-fastapi-app.modal.run';

  /**
   * 检查当前是否为H5平台 - 现在总是返回true
   * @private
   */
  private _isH5Platform(): boolean {
    return true; // H5版本总是返回true
  }

  /**
   * H5版本的文件上传方法
   * @private
   */
  private async _uploadFileForH5(params: UploadParams): Promise<string> {
    const { filePath, name, type, onProgress } = params;
    const url = `${this.baseUrl}/api/file/upload/s3`;

    try {
      // 自动生成文件名（如果未提供）
      const fileName = name || `upload_${Date.now()}.${this._getFileExtension(filePath)}`;
      // 自动判断文件类型（如果未提供）
      const fileType = type || this._getMimeType(filePath);

      console.log('开始上传文件 (H5模式):', {
        fileName,
        fileType,
      });

      // 创建FormData
      const formData = new FormData();

      // 在H5环境中，filePath可能是File对象或blob URL
      let file: File;
      if (filePath instanceof File) {
        file = filePath;
      } else if (typeof filePath === 'string') {
        // 如果是blob URL，转换为File对象
        const response = await fetch(filePath);
        const blob = await response.blob();
        file = new File([blob], fileName, { type: fileType });
      } else {
        throw new Error('不支持的文件类型');
      }

      formData.append('file', file);
      formData.append('filename', fileName);
      formData.append('type', fileType);

      // 使用fetch进行上传
      const uploadResponse = await fetch(url, {
        method: 'POST',
        body: formData,
        headers: {
          Accept: 'application/json',
        },
      });

      if (!uploadResponse.ok) {
        throw new Error(`HTTP ${uploadResponse.status}: 文件上传失败`);
      }

      const result: ApiResponse<string> = await uploadResponse.json();

      if (!result.status) {
        throw new Error(result.msg || '文件上传失败');
      }

      console.log('文件上传成功 (H5模式):', result.data);
      return result.data;
    } catch (error) {
      console.error('H5文件上传失败:', error);
      throw error;
    }
  }

  /**
   * H5版本的图像生成方法
   * @private
   */
  private async _generateImageForH5(params: GenerateImageParams): Promise<string> {
    const { prompt, model_name = 'gemini-2.5-flash-image-preview', aspect_ratio = '9:16', mode = 'turbo', webhook_flag = false, img_file } = params;

    const url = `${this.baseUrl}/api/custom/image/submit/task`;

    try {
      if (img_file) {
        // 创建FormData
        const formData = new FormData();

        // 处理文件对象
        let file: File;
        if (img_file instanceof File) {
          file = img_file;
        } else if (typeof img_file === 'string') {
          // 如果是blob URL，转换为File对象
          const response = await fetch(img_file);
          const blob = await response.blob();
          const fileName = `generate_${Date.now()}.${this._getFileExtension(img_file)}`;
          file = new File([blob], fileName, { type: this._getMimeType(img_file) });
        } else {
          throw new Error('不支持的文件类型');
        }

        formData.append('img_file', file);
        formData.append('prompt', prompt);
        formData.append('model_name', model_name);
        formData.append('aspect_ratio', aspect_ratio);
        formData.append('mode', mode.toString());
        formData.append('webhook_flag', webhook_flag.toString());
        formData.append('img_url', '');

        // 使用fetch进行上传
        const uploadResponse = await fetch(url, {
          method: 'POST',
          body: formData,
          headers: {
            accept: 'application/json',
          },
        });

        if (!uploadResponse.ok) {
          throw new Error(`HTTP ${uploadResponse.status}: 图像生成请求失败`);
        }

        const result: ApiResponse<string> = await uploadResponse.json();

        if (!result.status) {
          throw new Error(result.msg || '图像生成请求失败');
        }

        console.log('图像生成任务提交成功 (H5模式):', result.data);
        return result.data;
      }
      throw new Error(`请选择图片`);
    } catch (error) {
      console.error('H5图像生成失败:', error);
      throw error;
    }
  }

  /**
   * 上传文件到 S3
   * 支持图片、视频等多种文件类型上传
   * @param params 上传参数
   * @returns Promise<string> 返回上传后的文件地址
   */
  async upload(params: UploadParams): Promise<string> {
    // H5版本直接使用H5专用的上传方法
    return this._uploadFileForH5(params);
  }

  /**
   * 选择照片并上传 (H5版本)
   * 提供便捷的图片选择和上传功能，返回上传后的URL
   * @param options 选择图片的配置选项
   * @returns Promise<string> 返回上传后的文件URL
   */
  async chooseAndUploadImage(options?: {
    /** 最多可以选择的图片张数，默认为1 */
    count?: number;
    /** 所选的图片的尺寸，默认为 ['original', 'compressed'] */
    sizeType?: ('original' | 'compressed')[];
    /** 选择图片的来源，默认为 ['album', 'camera'] */
    sourceType?: ('album' | 'camera')[];
    /** 选择图片完成后的回调 */
    onImageSelected?: () => void;
    /** 上传进度回调 */
    onProgress?: (progress: number) => void;
  }): Promise<string> {
    const { onImageSelected, onProgress } = options || {};

    try {
      console.log('开始选择图片...');

      // H5版本使用文件选择器
      const file = await new Promise<File | null>(resolve => {
        const input = document.createElement('input');
        input.type = 'file';
        input.accept = 'image/*';
        input.style.display = 'none';

        document.body.appendChild(input);

        input.onchange = e => {
          const target = e.target as HTMLInputElement;
          const file = target.files?.[0] || null;
          document.body.removeChild(input);
          resolve(file);
        };

        input.click();
      });

      if (!file) {
        throw new Error('未选择图片');
      }

      console.log('图片选择结果:', file.name);

      // 选择图片完成后触发回调
      onImageSelected?.();

      // 上传图片
      console.log('开始上传图片:', file.name);

      const uploadUrl = await this.upload({
        filePath: file, // 传递File对象
        onProgress,
      });

      console.log('图片上传成功:', uploadUrl);
      return uploadUrl;
    } catch (error) {
      console.error('选择并上传图片失败:', error);
      throw error;
    }
  }

  // H5版本不需要授权相关方法

  /**
   * 选择并生成图片 (H5版本)
   * 封装了选择图片和生成的完整流程
   * @param options 选择图片的配置选项
   * @returns Promise<string> 返回任务ID
   */
  async chooseAndGenerateImage(options?: {
    /** 最多可以选择的图片张数，默认为1 */
    count?: number;
    /** 所选的图片的尺寸，默认为 ['original', 'compressed'] */
    sizeType?: ('original' | 'compressed')[];
    /** 选择图片的来源，默认为 ['album', 'camera'] */
    sourceType?: ('album' | 'camera')[];
    /** 选择图片完成后的回调 */
    onImageSelected?: () => void;
  }): Promise<string> {
    const { onImageSelected } = options || {};

    try {
      // H5版本使用文件选择器
      const file = await new Promise<File | null>(resolve => {
        const input = document.createElement('input');
        input.type = 'file';
        input.accept = 'image/*';
        input.style.display = 'none';

        document.body.appendChild(input);

        input.onchange = e => {
          const target = e.target as HTMLInputElement;
          const file = target.files?.[0] || null;
          document.body.removeChild(input);
          resolve(file);
        };

        input.click();
      });

      if (!file) {
        throw new Error('未选择图片');
      }

      console.log('图片选择结果:', file.name);

      // 选择图片完成后触发回调
      onImageSelected?.();

      // 生成图片
      const prompt = `Use nano banana style to create a 1/7 scale commercialized figure of the character in the illustration, in a realistic styie and environment.Place the figure on a computer desk, using a circular transparent acrylic base without any text.On the Macbook Pro screen, display the ZBrush modeling process of the figure in line mode. Next to the computer screen, place a BANDAl-style toy packaging box printedwith the original artwork.`;
      return await this.generateImage({
        img_file: file,
        prompt: prompt,
      });
    } catch (error) {
      console.error('选择并生成图片失败:', error);
      throw error;
    }
  }

  /**
   * 根据文件路径或文件名获取文件扩展名
   * @private
   */
  private _getFileExtension(filePath: string | File): string {
    let fileName: string;
    if (filePath instanceof File) {
      fileName = filePath.name;
    } else {
      fileName = filePath;
    }
    const match = fileName.match(/\.([^.]+)$/);
    return match ? match[1] : 'jpg';
  }

  /**
   * 根据文件路径或文件对象获取 MIME 类型
   * @private
   */
  private _getMimeType(filePath: string | File): string {
    // 如果是File对象，优先使用其type属性
    if (filePath instanceof File && filePath.type) {
      return filePath.type;
    }

    const extension = this._getFileExtension(filePath).toLowerCase();
    const mimeTypes: Record<string, string> = {
      jpg: 'image/jpeg',
      jpeg: 'image/jpeg',
      png: 'image/png',
      gif: 'image/gif',
      webp: 'image/webp',
      mp4: 'video/mp4',
      mov: 'video/quicktime',
      avi: 'video/x-msvideo',
    };
    return mimeTypes[extension] || 'application/octet-stream';
  }

  /**
   * 生成图像
   * @param params 图像生成参数
   * @returns Promise<string> 返回任务ID
   *
   * 使用 multipart/form-data 格式提交，支持文件上传和URL参数
   * 对应 curl 命令：
   * curl -X 'POST' \
   *   'https://bowongai-test--text-video-agent-fastapi-app.modal.run/api/custom/image/submit/task' \
   *   -H 'accept: application/json' \
   *   -H 'Content-Type: multipart/form-data' \
   *   -F 'prompt=...' \
   *   -F 'model_name=gemini-2.5-flash-image-preview' \
   *   -F 'aspect_ratio=9:16' \
   *   -F 'mode=turbo' \
   *   -F 'webhook_flag=false' \
   *   -F 'img_url=https://...' \
   *   -F 'img_file='
   */
  async generateImage(params: GenerateImageParams): Promise<string> {
    // H5版本直接使用H5专用的生成方法
    return this._generateImageForH5(params);
  }

  /**
   * 查询任务状态
   * @param taskId 任务ID
   * @param retryCount 内部重试计数，外部调用不需要传入
   * @returns Promise<any> 返回任务状态信息
   */
  async getTaskStatus(taskId: string, retryCount: number = 0): Promise<string[]> {
    const url = `${this.baseUrl}/api/custom/task/status?task_id=${taskId}`;
    const maxRetries = 3;

    try {
      const response = await fetch(url, {
        method: 'GET',
        headers: {
          Accept: 'application/json',
        },
      });

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: 查询任务状态失败`);
      }

      const result = (await response.json()) as ApiResponse;
      if (!result.status) {
        throw new Error(result.msg || '查询任务状态失败');
      }

      if (result.status === 'running') {
        await new Promise(resolve => setTimeout(resolve, 1000 * 5));
        return this.getTaskStatus(taskId);
      }

      return result.data;
    } catch (error) {
      console.error(`查询任务状态失败 (第${retryCount + 1}次尝试):`, error);

      // 如果重试次数未达到最大值，等待5秒后重试
      if (retryCount < maxRetries) {
        console.log(`将在5秒后进行第${retryCount + 2}次重试...`);
        await new Promise(resolve => setTimeout(resolve, 5000));
        return this.getTaskStatus(taskId, retryCount + 1);
      }

      // 超过最大重试次数，抛出异常
      throw new Error(`查询任务状态失败，已重试${maxRetries}次: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  /**
   * 图像转视频
   * @param params 图像转视频参数
   * @returns Promise<string> 返回任务ID
   *
   * 对应 curl 命令：
   * curl -X 'POST' \
   *   'https://bowongai-test--text-video-agent-fastapi-app.modal.run/api/custom/transform/i2v' \
   *   -H 'accept: application/json' \
   *   -H 'Content-Type: application/x-www-form-urlencoded' \
   *   -d 'img_url=string&duration=0'
   */
  async imageToVideo(params: ImageToVideoParams): Promise<string> {
    const { img_url, duration = 0 } = params;
    const url = `${this.baseUrl}/api/custom/transform/i2v`;

    try {
      // 构建 form data
      const formData = new URLSearchParams();
      formData.append('img_url', img_url);
      formData.append('duration', duration.toString());

      const response = await fetch(url, {
        method: 'POST',
        headers: {
          accept: 'application/json',
          'Content-Type': 'application/x-www-form-urlencoded',
        },
        body: formData.toString(),
      });

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: 图像转视频请求失败`);
      }

      const result = (await response.json()) as ApiResponse<string>;

      if (!result.status) {
        throw new Error(result.msg || '图像转视频请求失败');
      }

      console.log('图像转视频任务提交成功:', result.data);
      return result.data;
    } catch (error) {
      console.error('图像转视频失败:', error);
      throw error;
    }
  }
}

/**
 * 使用示例：
 *
 * // 1. 选择并上传图片
 * const uploadResult = await bowongAI.chooseAndUploadImage({
 *   onProgress: (progress) => console.log(`上传进度: ${progress}%`)
 * });
 *
 * // 2. 使用上传的图片生成新图像
 * const generateResult = await bowongAI.generateImage({
 *   img_url: uploadResult.file_url,
 *   prompt: '转换为油画风格'
 * });
 *
 * // 3. 查询生成状态
 * const status = await bowongAI.getTaskStatus(generateResult.task_id);
 *
 * // 4. 获取最终结果
 * const finalResult = await bowongAI.getTaskResult(generateResult.task_id);
 */

// 导出 SDK 实例（可以传入自定义的模板服务器URL）
export const bowongAI = new BowongAISDK();

// 向后兼容的类名导出
export const Sdk = BowongAISDK;
