'use client';

const MAX_FILE_SIZE = 150 * 1024; // 150 KB

/**
 * Optimizes an image file to be at most 150KB using canvas compression.
 * Iteratively reduces quality and dimensions until the target size is reached.
 * Returns the original file if it's already under the limit.
 */
export async function optimizeImageForUpload(file: File): Promise<File> {
  // Skip non-image files (e.g. PDFs, videos)
  if (!file.type.startsWith('image/')) return file;

  // If already under limit, return as-is
  if (file.size <= MAX_FILE_SIZE) return file;

  const bitmap = await createImageBitmap(file);
  let { width, height } = bitmap;

  // Iteratively reduce quality, then dimensions
  const qualities = [0.8, 0.65, 0.5, 0.4, 0.3, 0.2];
  const scaleFactors = [1, 0.85, 0.7, 0.55, 0.4];

  for (const scale of scaleFactors) {
    const targetW = Math.round(width * scale);
    const targetH = Math.round(height * scale);

    for (const quality of qualities) {
      const blob = await compressToBlob(bitmap, targetW, targetH, quality);
      if (blob.size <= MAX_FILE_SIZE) {
        bitmap.close();
        return new File([blob], file.name.replace(/\.[^.]+$/, '.webp'), {
          type: 'image/webp',
          lastModified: Date.now(),
        });
      }
    }
  }

  // Final fallback: aggressive resize + low quality
  const blob = await compressToBlob(bitmap, Math.min(width, 640), Math.min(height, 480), 0.15);
  bitmap.close();
  return new File([blob], file.name.replace(/\.[^.]+$/, '.webp'), {
    type: 'image/webp',
    lastModified: Date.now(),
  });
}

function compressToBlob(
  bitmap: ImageBitmap,
  width: number,
  height: number,
  quality: number
): Promise<Blob> {
  return new Promise((resolve, reject) => {
    const canvas = document.createElement('canvas');
    canvas.width = width;
    canvas.height = height;
    const ctx = canvas.getContext('2d');
    if (!ctx) return reject(new Error('Failed to get canvas context'));
    ctx.drawImage(bitmap, 0, 0, width, height);
    canvas.toBlob(
      (blob) => {
        if (!blob) return reject(new Error('Canvas to Blob failed'));
        resolve(blob);
      },
      'image/webp',
      quality
    );
  });
}
