import imageCompression from 'browser-image-compression';

/**
 * Client-side image compression shared by every photo upload (expense receipts,
 * offering paper-proofs). Phone cameras produce 12MP+ JPEGs that are several MB
 * each; resizing the longest edge and re-encoding as JPEG keeps uploads small
 * enough to clear the API's per-endpoint size limits (and the reverse proxy).
 *
 * Tunables: raise quality/edge if proofs look too soft; lower them if files are
 * too large.
 */
export class ImageUtils {
    /** Longest image edge (px) after compression. */
    public static readonly MAX_EDGE_PX = 2000;
    /** JPEG encoder quality, 0..1. */
    public static readonly JPEG_QUALITY = 0.72;
    /** Target ceiling per image, in megabytes. */
    public static readonly MAX_SIZE_MB = 1;

    /**
     * Compresses a single image File to a resized JPEG. Non-image files (e.g. a
     * PDF) are returned untouched.
     *
     * The result is always renamed to a ".jpg" extension with an "image/jpeg"
     * type, because the API derives a stored receipt's content-type from its
     * filename extension — keeping a ".png" name on JPEG bytes would make the
     * download serve a broken image.
     */
    public static async compressForUpload(file: File): Promise<File> {
        if (!file.type.startsWith('image/')) {
            return file;
        }

        const compressed = await imageCompression(file, {
            maxWidthOrHeight: ImageUtils.MAX_EDGE_PX,
            maxSizeMB: ImageUtils.MAX_SIZE_MB,
            initialQuality: ImageUtils.JPEG_QUALITY,
            fileType: 'image/jpeg',
            useWebWorker: true,
        });

        const baseName = file.name.replace(/\.[^.]+$/, '');
        return new File([compressed], `${baseName}.jpg`, { type: 'image/jpeg' });
    }
}
