/**
 * 压缩图片到指定大小
 * @param file 原始图片文件
 * @param maxSizeInMB 最大文件大小（MB）
 * @param quality 初始压缩质量（0-1）
 * @returns 压缩后的文件
 */
export const compressImage = async (
  file: File,
  maxSizeInMB: number = 1,
  quality: number = 0.9
): Promise<File> => {
  const maxSizeInBytes = maxSizeInMB * 1024 * 1024;
  
  // AVIF 和 WebP 需要转换为 JPEG，即使文件小于目标大小
  const needsConversion = file.type === 'image/avif' || file.type === 'image/webp';

  // 如果文件已经小于目标大小且不需要格式转换，直接返回
  if (file.size <= maxSizeInBytes && !needsConversion) {
    return file;
  }

  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = (event) => {
      const img = new Image();
      img.src = event.target?.result as string;
      
      img.onload = () => {
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        
        if (!ctx) {
          reject(new Error('无法获取 canvas context'));
          return;
        }

        // 保持原始尺寸
        canvas.width = img.width;
        canvas.height = img.height;
        
        // 绘制图片
        ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
        
        // 统一输出 JPEG：canvas.toBlob 的 quality 参数仅对 image/jpeg 有效
        // PNG 等无损格式通过 Canvas 重新编码后可能反而变大，导致突破 bucket 大小限制
        const outputType = 'image/jpeg';
        
        // 生成新的文件名（如果格式改变）
        const getNewFileName = (originalName: string, newType: string) => {
          if (newType === file.type) return originalName;
          const nameWithoutExt = originalName.replace(/\.[^/.]+$/, '');
          const newExt = newType.split('/')[1];
          return `${nameWithoutExt}.${newExt}`;
        };
        
        // 递归压缩直到满足大小要求
        const compress = (currentQuality: number) => {
          canvas.toBlob(
            (blob) => {
              if (!blob) {
                reject(new Error('压缩失败'));
                return;
              }

              // 如果大小符合要求或质量已经很低，返回结果
              if (blob.size <= maxSizeInBytes || currentQuality <= 0.1) {
                const compressedFile = new File(
                  [blob],
                  getNewFileName(file.name, outputType),
                  {
                    type: outputType,
                    lastModified: Date.now(),
                  }
                );
                resolve(compressedFile);
              } else {
                // 继续降低质量
                compress(currentQuality - 0.1);
              }
            },
            outputType,
            currentQuality
          );
        };
        
        compress(quality);
      };
      
      img.onerror = () => {
        reject(new Error('图片加载失败'));
      };
    };
    
    reader.onerror = () => {
      reject(new Error('文件读取失败'));
    };
  });
};
