// src/utils/checksum.ts
import { logger } from '../services/logger.client';

/**
 * Helper to read file as ArrayBuffer using FileReader (fallback for environments missing file.arrayBuffer)
 */
const readFileAsArrayBuffer = (file: File): Promise<ArrayBuffer> => {
    return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = () => {
            if (reader.result instanceof ArrayBuffer) {
                resolve(reader.result);
            } else {
                reject(new Error('FileReader result was not an ArrayBuffer'));
            }
        };
        reader.onerror = () => {
            reject(new Error(`FileReader error: ${reader.error?.message}`));
        };
        reader.readAsArrayBuffer(file);
    });
};

/**
 * Generates a SHA-256 checksum for a file.
 * @param file The file to hash.
 * @returns A promise that resolves to the hex string of the checksum.
 */
export const generateFileChecksum = async (file: File): Promise<string> => {
    // Debugging: Log file details to ensure we are receiving what we expect
    logger.debug(`generateFileChecksum processing file: name="${file.name}", type="${file.type}", size=${file.size}`);

    let buffer: ArrayBuffer;

    // Check if arrayBuffer exists on the file object (it may be missing in JSDOM or older environments)
    if (typeof file.arrayBuffer === 'function') {
        try {
            buffer = await file.arrayBuffer();
        } catch (error) {
            logger.warn('file.arrayBuffer() threw an error, falling back to FileReader:', { error });
            buffer = await readFileAsArrayBuffer(file);
        }
    } else {
        logger.warn('file.arrayBuffer is not a function on this File object. Using FileReader fallback.');
        buffer = await readFileAsArrayBuffer(file);
    }

    // Debugging: Verify crypto availability
    if (!crypto || !crypto.subtle) {
        logger.error('crypto.subtle is not available in this environment. SHA-256 generation will fail.');
    }

    // Ensure buffer is a TypedArray or ArrayBuffer that crypto.subtle accepts
    // Wrapping in Uint8Array handles both ArrayBuffer and SharedArrayBuffer, and helps with JSDOM compatibility
    const hashBuffer = await crypto.subtle.digest('SHA-256', new Uint8Array(buffer));
    const hashArray = Array.from(new Uint8Array(hashBuffer));
    const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
    return hashHex;
};
