/* eslint-disable */
// file-upload-helper.js
// 通用文件上传工具

if (window.__FILE_UPLOAD_HELPER_INITIALIZED__) {
  // Already initialized, skip
} else {
  window.__FILE_UPLOAD_HELPER_INITIALIZED__ = true;

  /**
   * 通用文件上传工具类
   */
  class FileUploadHelper {
    /**
     * 从 URL 上传文件
     * @param {string} url - 文件 URL
     * @param {string} filename - 文件名，默认从 URL 推断
     * @param {string} mimeType - MIME 类型，默认从文件扩展名推断
     * @param {string} inputSelector - 文件输入框选择器，默认 'input[type="file"]'
     * @param {number} timeout - 等待文件输入框的超时时间
     * @returns {Promise<Object>} 上传结果
     */
    static async uploadFromUrl(
      url,
      filename = null,
      mimeType = null,
      inputSelector = 'input[type="file"]',
      timeout = 10000,
    ) {
      try {
        // 1. 获取文件数据
        const response = await fetch(url);
        if (!response.ok) {
          throw new Error(`Failed to fetch file from URL: ${response.status}`);
        }

        const blob = await response.blob();

        // 2. 推断文件名和类型
        if (!filename) {
          filename = url.split('/').pop() || 'file';
          // 确保有扩展名
          if (!filename.includes('.')) {
            const contentType = response.headers.get('content-type') || blob.type;
            const extension = FileUploadHelper._getExtensionFromMimeType(contentType);
            filename += extension;
          }
        }

        if (!mimeType) {
          mimeType = blob.type || FileUploadHelper._getMimeTypeFromFilename(filename);
        }

        // 3. 特殊处理图片类型（参考小红书扩展）
        if (mimeType.startsWith('image/') || filename.match(/\.(jpg|jpeg|png|gif|webp)$/i)) {
          // 对于图片，默认使用 image/jpeg 和 .jpg
          if (!filename.match(/\.(jpg|jpeg|png|gif|webp)$/i)) {
            filename = filename.replace(/\.[^.]*$/, '') + '.jpg';
          }
          if (mimeType === 'application/octet-stream' || !mimeType.startsWith('image/')) {
            mimeType = 'image/jpeg';
          }
        }

        console.log(`Uploading from URL: ${filename}, type: ${mimeType}, size: ${blob.size}`);

        // 4. 创建文件对象
        const file = new File([blob], filename, { type: mimeType });

        // 5. 上传文件
        return await FileUploadHelper.uploadFile(file, inputSelector, timeout);
      } catch (error) {
        return {
          success: false,
          error: `Error uploading from URL: ${error.message}`,
        };
      }
    }

    /**
     * 从 Base64 数据上传文件
     * @param {string} base64Data - Base64 编码的文件数据
     * @param {string} filename - 文件名
     * @param {string} mimeType - MIME 类型
     * @param {string} inputSelector - 文件输入框选择器
     * @param {number} timeout - 超时时间
     * @returns {Promise<Object>} 上传结果
     */
    static async uploadFromBase64(
      base64Data,
      filename = 'file',
      mimeType = null,
      inputSelector = 'input[type="file"]',
      timeout = 10000,
    ) {
      try {
        // 智能推断文件类型和名称
        const { detectedType, detectedName } = FileUploadHelper._detectFileTypeFromBase64(
          base64Data,
          filename,
          mimeType,
        );

        // 转换 base64 为 Blob
        const blob = FileUploadHelper._base64ToBlob(base64Data, detectedType);

        // 创建 File 对象
        const file = new File([blob], detectedName, { type: detectedType });

        console.log(`Uploading file: ${detectedName}, type: ${detectedType}, size: ${blob.size}`);

        // 上传文件
        return await FileUploadHelper.uploadFile(file, inputSelector, timeout);
      } catch (error) {
        return {
          success: false,
          error: `Error uploading from base64: ${error.message}`,
        };
      }
    }

    /**
     * 将 Base64 转换为 Blob
     * @param {string} base64Data - Base64 数据
     * @param {string} mimeType - MIME 类型
     * @returns {Blob} Blob 对象
     */
    static _base64ToBlob(base64Data, mimeType = 'application/octet-stream') {
      // 移除 data URL 前缀（如果存在）
      const base64 = base64Data.replace(/^data:[^;]+;base64,/, '');

      try {
        const binary = atob(base64);
        const bytes = new Uint8Array(binary.length);

        for (let i = 0; i < binary.length; i++) {
          bytes[i] = binary.charCodeAt(i);
        }

        return new Blob([bytes], { type: mimeType });
      } catch (error) {
        throw new Error(`Invalid base64 data: ${error.message}`);
      }
    }

    /**
     * 上传本地文件（通过文件路径）
     * @param {string} _filePath - 文件路径（保留用于接口兼容）
     * @param {string} inputSelector - 文件输入框选择器
     * @param {number} timeout - 超时时间
     * @returns {Promise<Object>} 上传结果
     */
    static async uploadFromPath(_filePath, inputSelector = 'input[type="file"]', timeout = 10000) {
      try {
        // 等待文件输入元素出现
        const fileInput = await window.DOMUtils.waitForElement(inputSelector, timeout);

        // 提示用户选择文件（需要用户交互）
        return new Promise((resolve) => {
          // 创建一个临时的文件监听器
          const handleFileChange = () => {
            fileInput.removeEventListener('change', handleFileChange);

            if (fileInput.files.length > 0) {
              // 触发 change 事件
              fileInput.dispatchEvent(new Event('change', { bubbles: true }));

              resolve({
                success: true,
                message: 'File uploaded successfully',
                fileCount: fileInput.files.length,
                files: Array.from(fileInput.files).map((f) => ({
                  name: f.name,
                  size: f.size,
                  type: f.type,
                })),
              });
            } else {
              resolve({
                success: false,
                error: 'No file selected',
              });
            }
          };

          fileInput.addEventListener('change', handleFileChange);

          // 触发文件选择对话框
          fileInput.click();
        });
      } catch (error) {
        return {
          success: false,
          error: `Error uploading from path: ${error.message}`,
        };
      }
    }

    /**
     * 直接上传文件对象
     * @param {File} file - 文件对象
     * @param {string} inputSelector - 文件输入框选择器
     * @param {number} timeout - 超时时间
     * @returns {Promise<Object>} 上传结果
     */
    static async uploadFile(file, inputSelector = 'input[type="file"]', timeout = 10000) {
      try {
        // 等待文件输入元素出现
        const fileInput = await window.DOMUtils.waitForElement(inputSelector, timeout);

        // 创建 DataTransfer 对象来模拟文件选择
        const dataTransfer = new DataTransfer();
        dataTransfer.items.add(file);
        fileInput.files = dataTransfer.files;

        // 触发 change 事件
        fileInput.dispatchEvent(new Event('change', { bubbles: true }));

        // 等待一段时间确保上传完成
        await window.DOMUtils.sleep(1000);

        return {
          success: true,
          message: 'File uploaded successfully',
          file: {
            name: file.name,
            size: file.size,
            type: file.type,
          },
        };
      } catch (error) {
        return {
          success: false,
          error: `Error uploading file: ${error.message}`,
        };
      }
    }

    /**
     * 批量上传多个文件
     * @param {Array} files - 文件数组（可以是 File 对象、URL 字符串或路径字符串）
     * @param {string} inputSelector - 文件输入框选择器
     * @param {Object} options - 选项
     * @returns {Promise<Object>} 上传结果
     */
    static async uploadMultipleFiles(files, inputSelector = 'input[type="file"]', options = {}) {
      const {
        timeout = 10000,
        sequential = true, // 是否顺序上传
        allowFailure = true, // 是否允许部分失败
      } = options;

      const results = [];
      const errors = [];

      try {
        if (sequential) {
          // 顺序上传
          for (let i = 0; i < files.length; i++) {
            const file = files[i];
            let result;

            if (typeof file === 'string') {
              // 判断是 URL 还是路径
              if (file.startsWith('http')) {
                result = await FileUploadHelper.uploadFromUrl(
                  file,
                  null,
                  null,
                  inputSelector,
                  timeout,
                );
              } else {
                result = await FileUploadHelper.uploadFromPath(file, inputSelector, timeout);
              }
            } else if (file instanceof File) {
              result = await FileUploadHelper.uploadFile(file, inputSelector, timeout);
            } else if (typeof file === 'object' && file.type) {
              // 新的数据结构
              if (file.type === 'url') {
                result = await FileUploadHelper.uploadFromUrl(
                  file.url,
                  file.filename,
                  file.mimeType,
                  inputSelector,
                  timeout,
                );
              } else if (file.type === 'base64') {
                result = await FileUploadHelper.uploadFromBase64(
                  file.base64Data,
                  file.filename,
                  file.mimeType,
                  inputSelector,
                  timeout,
                );
              } else {
                result = {
                  success: false,
                  error: 'Unsupported file type: ' + file.type,
                };
              }
            } else {
              result = {
                success: false,
                error: 'Unsupported file type',
              };
            }

            results.push(result);

            if (!result.success) {
              errors.push({ index: i, file, error: result.error });
              if (!allowFailure) {
                break;
              }
            }

            // 文件间延迟
            if (i < files.length - 1) {
              await window.DOMUtils.sleep(500);
            }
          }
        } else {
          // 并行上传（注意：大多数网站不支持真正的并行文件上传）
          const promises = files.map(async (file, index) => {
            let result;

            if (typeof file === 'string') {
              if (file.startsWith('http')) {
                result = await FileUploadHelper.uploadFromUrl(
                  file,
                  null,
                  null,
                  inputSelector,
                  timeout,
                );
              } else {
                result = await FileUploadHelper.uploadFromPath(file, inputSelector, timeout);
              }
            } else if (file instanceof File) {
              result = await FileUploadHelper.uploadFile(file, inputSelector, timeout);
            } else if (typeof file === 'object' && file.type) {
              // 新的数据结构
              if (file.type === 'url') {
                result = await FileUploadHelper.uploadFromUrl(
                  file.url,
                  file.filename,
                  file.mimeType,
                  inputSelector,
                  timeout,
                );
              } else if (file.type === 'base64') {
                result = await FileUploadHelper.uploadFromBase64(
                  file.base64Data,
                  file.filename,
                  file.mimeType,
                  inputSelector,
                  timeout,
                );
              } else {
                result = {
                  success: false,
                  error: 'Unsupported file type: ' + file.type,
                };
              }
            } else {
              result = {
                success: false,
                error: 'Unsupported file type',
              };
            }

            if (!result.success) {
              errors.push({ index, file, error: result.error });
            }

            return result;
          });

          const parallelResults = await Promise.all(promises);
          results.push(...parallelResults);
        }

        const successCount = results.filter((r) => r.success).length;
        const failCount = results.filter((r) => !r.success).length;

        return {
          success: failCount === 0 || (allowFailure && successCount > 0),
          message: `Upload completed: ${successCount} succeeded, ${failCount} failed`,
          totalFiles: files.length,
          successCount,
          failCount,
          results,
          errors,
        };
      } catch (error) {
        return {
          success: false,
          error: `Batch upload error: ${error.message}`,
          results,
          errors,
        };
      }
    }

    /**
     * 上传拖拽文件
     * @param {string} dropZoneSelector - 拖拽区域选择器
     * @param {Array} files - 文件数组
     * @returns {Promise<Object>} 上传结果
     */
    static async uploadByDragDrop(dropZoneSelector, files) {
      try {
        const dropZone = await window.DOMUtils.waitForElement(dropZoneSelector);

        // 创建拖拽事件
        const dataTransfer = new DataTransfer();

        for (const file of files) {
          if (file instanceof File) {
            dataTransfer.items.add(file);
          } else if (typeof file === 'object' && file.type) {
            // 新的数据结构，需要转换为 File 对象
            let fileObj;
            if (file.type === 'base64') {
              const blob = FileUploadHelper._base64ToBlob(file.base64Data, file.mimeType);
              fileObj = new File([blob], file.filename, { type: file.mimeType });
            } else if (file.type === 'url') {
              // URL 文件需要先下载
              try {
                const response = await fetch(file.url);
                const blob = await response.blob();
                fileObj = new File([blob], file.filename || 'file', {
                  type: file.mimeType || blob.type,
                });
              } catch (error) {
                console.error('Failed to fetch file from URL:', error);
                continue;
              }
            }
            if (fileObj) {
              dataTransfer.items.add(fileObj);
            }
          }
        }

        // 模拟拖拽事件序列
        const dragEnterEvent = new DragEvent('dragenter', {
          bubbles: true,
          cancelable: true,
          dataTransfer,
        });

        const dragOverEvent = new DragEvent('dragover', {
          bubbles: true,
          cancelable: true,
          dataTransfer,
        });

        const dropEvent = new DragEvent('drop', {
          bubbles: true,
          cancelable: true,
          dataTransfer,
        });

        dropZone.dispatchEvent(dragEnterEvent);
        await window.DOMUtils.sleep(100);

        dropZone.dispatchEvent(dragOverEvent);
        await window.DOMUtils.sleep(100);

        dropZone.dispatchEvent(dropEvent);

        return {
          success: true,
          message: 'Files dropped successfully',
          fileCount: files.length,
        };
      } catch (error) {
        return {
          success: false,
          error: `Drag and drop upload error: ${error.message}`,
        };
      }
    }

    // 辅助方法：从 MIME 类型获取文件扩展名
    static _getExtensionFromMimeType(mimeType) {
      const mimeMap = {
        'image/jpeg': '.jpg',
        'image/png': '.png',
        'image/gif': '.gif',
        'image/webp': '.webp',
        'image/svg+xml': '.svg',
        'text/plain': '.txt',
        'text/html': '.html',
        'application/pdf': '.pdf',
        'application/json': '.json',
        'video/mp4': '.mp4',
        'video/webm': '.webm',
        'audio/mp3': '.mp3',
        'audio/wav': '.wav',
      };
      return mimeMap[mimeType] || '';
    }

    // 辅助方法：从文件名获取 MIME 类型
    static _getMimeTypeFromFilename(filename) {
      const extension = filename.split('.').pop().toLowerCase();
      const extMap = {
        jpg: 'image/jpeg',
        jpeg: 'image/jpeg',
        png: 'image/png',
        gif: 'image/gif',
        webp: 'image/webp',
        svg: 'image/svg+xml',
        txt: 'text/plain',
        html: 'text/html',
        pdf: 'application/pdf',
        json: 'application/json',
        mp4: 'video/mp4',
        webm: 'video/webm',
        mp3: 'audio/mp3',
        wav: 'audio/wav',
      };
      return extMap[extension] || 'application/octet-stream';
    }

    // 智能检测文件类型和名称
    static _detectFileTypeFromBase64(base64Data, filename, providedMimeType) {
      let detectedType = providedMimeType;
      let detectedName = filename;

      // 移除 data URL 前缀并检测类型
      const cleanBase64 = base64Data.replace(/^data:([^;]+);base64,/, (_, mimeType) => {
        if (!detectedType) {
          detectedType = mimeType;
        }
        return '';
      });

      // 通过 base64 开头的魔数检测文件类型
      if (!detectedType || detectedType === 'application/octet-stream') {
        const signatures = {
          '/9j/': { type: 'image/jpeg', ext: '.jpg' },
          iVBORw0KGgo: { type: 'image/png', ext: '.png' },
          R0lGOD: { type: 'image/gif', ext: '.gif' },
          UklGR: { type: 'image/webp', ext: '.webp' },
          JVBERi0: { type: 'application/pdf', ext: '.pdf' },
          UEsDBBQ: { type: 'application/zip', ext: '.zip' },
        };

        for (const [signature, info] of Object.entries(signatures)) {
          if (cleanBase64.startsWith(signature)) {
            detectedType = info.type;
            // 如果文件名没有扩展名，添加检测到的扩展名
            if (!detectedName.includes('.')) {
              detectedName += info.ext;
            }
            break;
          }
        }
      }

      // 如果还是没有检测到类型，根据文件名推断
      if (!detectedType || detectedType === 'application/octet-stream') {
        if (detectedName.includes('.')) {
          detectedType = FileUploadHelper._getMimeTypeFromFilename(detectedName);
        } else {
          // 默认为图片（参考小红书扩展的做法）
          detectedType = 'image/jpeg';
          detectedName = detectedName + '.jpg';
        }
      }

      // 特殊处理：如果是图片但没有合适的扩展名，统一使用 .jpg
      if (
        detectedType.startsWith('image/') &&
        !detectedName.match(/\.(jpg|jpeg|png|gif|webp|svg)$/i)
      ) {
        if (detectedType === 'image/png') {
          detectedName = detectedName.replace(/\.[^.]*$/, '') + '.png';
        } else {
          detectedName = detectedName.replace(/\.[^.]*$/, '') + '.jpg';
          detectedType = 'image/jpeg'; // 强制使用 JPEG
        }
      }

      console.log(`File type detection: ${detectedName} -> ${detectedType}`);

      return {
        detectedType,
        detectedName,
      };
    }
  }

  // 监听来自扩展的消息
  chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
    if (request.action === 'uploadFromUrl') {
      FileUploadHelper.uploadFromUrl(
        request.url,
        request.filename,
        request.mimeType,
        request.inputSelector,
        request.timeout,
      )
        .then(sendResponse)
        .catch((error) => {
          sendResponse({
            success: false,
            error: error.message,
          });
        });
      return true; // 异步响应
    }

    if (request.action === 'uploadFromBase64') {
      FileUploadHelper.uploadFromBase64(
        request.base64Data,
        request.filename,
        request.mimeType,
        request.inputSelector,
        request.timeout,
      )
        .then(sendResponse)
        .catch((error) => {
          sendResponse({
            success: false,
            error: error.message,
          });
        });
      return true; // 异步响应
    }

    if (request.action === 'uploadFromPath') {
      FileUploadHelper.uploadFromPath(request.filePath, request.inputSelector, request.timeout)
        .then(sendResponse)
        .catch((error) => {
          sendResponse({
            success: false,
            error: error.message,
          });
        });
      return true; // 异步响应
    }

    if (request.action === 'uploadMultipleFiles') {
      FileUploadHelper.uploadMultipleFiles(request.files, request.inputSelector, request.options)
        .then(sendResponse)
        .catch((error) => {
          sendResponse({
            success: false,
            error: error.message,
          });
        });
      return true; // 异步响应
    }

    if (request.action === 'uploadByDragDrop') {
      FileUploadHelper.uploadByDragDrop(request.dropZoneSelector, request.files)
        .then(sendResponse)
        .catch((error) => {
          sendResponse({
            success: false,
            error: error.message,
          });
        });
      return true; // 异步响应
    }

    if (request.action === 'chrome_file_upload_ping') {
      sendResponse({ status: 'pong' });
      return false;
    }
  });

  // 将工具类暴露到全局
  window.FileUploadHelper = FileUploadHelper;
}
