/**
 * Image processing utilities for resizing and encoding images
 */

export interface ProcessedImage {
    dataUrl: string;
    blob: Blob;
    width: number;
    height: number;
    originalSize: number;
    compressedSize: number;
}

/**
 * Resize an image to a specific size and convert to base64
 * @param file - The image file to process
 * @param maxWidth - Maximum width (default: 128)
 * @param maxHeight - Maximum height (default: 128)
 * @param quality - JPEG quality (0-1, default: 0.8)
 * @returns Promise with processed image data
 */
export const processImage = async (
    file: File,
    maxWidth: number = 128,
    maxHeight: number = 128,
    quality: number = 0.8
): Promise<ProcessedImage> => {
    return new Promise((resolve, reject) => {
        // Validate file type
        if (!file.type.startsWith('image/')) {
            reject(new Error('File must be an image'));
            return;
        }

        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        const img = new Image();

        img.onload = () => {
            // Clean up the object URL to free memory
            URL.revokeObjectURL(img.src);
            
            // Calculate dimensions to maintain aspect ratio
            let { width, height } = calculateDimensions(
                img.width,
                img.height,
                maxWidth,
                maxHeight
            );

            canvas.width = width;
            canvas.height = height;

            // Draw and resize image
            ctx!.imageSmoothingEnabled = true;
            ctx!.imageSmoothingQuality = 'high';
            ctx!.drawImage(img, 0, 0, width, height);

            // Convert to blob and data URL
            canvas.toBlob(
                (blob) => {
                    if (!blob) {
                        reject(new Error('Failed to process image'));
                        return;
                    }

                    const dataUrl = canvas.toDataURL('image/jpeg', quality);

                    resolve({
                        dataUrl,
                        blob,
                        width,
                        height,
                        originalSize: file.size,
                        compressedSize: blob.size,
                    });
                },
                'image/jpeg',
                quality
            );
        };

        img.onerror = () => {
            // Clean up the object URL in case of error
            URL.revokeObjectURL(img.src);
            reject(new Error('Failed to load image'));
        };

        // Load the image
        img.src = URL.createObjectURL(file);
    });
};

/**
 * Calculate dimensions to fit within max bounds while maintaining aspect ratio
 */
const calculateDimensions = (
    originalWidth: number,
    originalHeight: number,
    maxWidth: number,
    maxHeight: number
): { width: number; height: number } => {
    const aspectRatio = originalWidth / originalHeight;

    let width = maxWidth;
    let height = maxHeight;

    if (originalWidth > originalHeight) {
        // Landscape
        height = width / aspectRatio;
        if (height > maxHeight) {
            height = maxHeight;
            width = height * aspectRatio;
        }
    } else {
        // Portrait or square
        width = height * aspectRatio;
        if (width > maxWidth) {
            width = maxWidth;
            height = width / aspectRatio;
        }
    }

    return {
        width: Math.round(width),
        height: Math.round(height),
    };
};

/**
 * Validate image file
 */
export const validateImageFile = (file: File): { valid: boolean; error?: string } => {
    // Check file type
    if (!file.type.startsWith('image/')) {
        return { valid: false, error: 'File must be an image' };
    }

    // Check file size (max 10MB)
    const maxSize = 10 * 1024 * 1024; // 10MB
    if (file.size > maxSize) {
        return { valid: false, error: 'Image must be smaller than 10MB' };
    }

    // Check supported formats
    const supportedTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp'];
    if (!supportedTypes.includes(file.type)) {
        return { valid: false, error: 'Supported formats: JPEG, PNG, GIF, WebP' };
    }

    return { valid: true };
};

/**
 * Generate a unique filename
 */
export const generateUniqueFileName = (originalName: string, prefix: string = 'img'): string => {
    const timestamp = Date.now();
    const random = Math.random().toString(36).substring(2, 8);
    const extension = originalName.split('.').pop() || 'jpg';
    return `${prefix}_${timestamp}_${random}.${extension}`;
};