/**
 * Allowed file types based on magic numbers
 */
const ALLOWED_IMAGE_MAGIC_TYPES = [
    'image/jpeg',
    'image/png',
    'image/gif',
    'image/webp'
];

// Audio MIME types that are actually video containers
const ALLOWED_AUDIO_VIDEO_CONTAINERS = [
    'audio/x-ms-asf', // WMV files sometimes detected as audio
    'audio/mp4' // Some MP4 videos detected as audio
];

/**
 * Maximum file sizes
 */
export const MAX_IMAGE_SIZE = 10 * 1024 * 1024; // 10MB
export const MAX_VIDEO_SIZE = 50 * 1024 * 1024; // 50MB

/**
 * Validate file type using magic numbers (file signature)
 * This is more secure than relying on MIME type or file extension
 */
export async function validateFileType(buffer: Buffer): Promise<{ valid: boolean; message?: string; detectedType?: string }> {
    try {
        // Dynamically import file-type (ES module)
        const { fileTypeFromBuffer } = await import('file-type');

        // Detect file type from buffer using magic numbers
        const fileType = await fileTypeFromBuffer(buffer);

        if (!fileType) {
            return {
                valid: false,
                message: 'Unable to determine file type. File may be corrupted or unsupported'
            };
        }

        const isImage = ALLOWED_IMAGE_MAGIC_TYPES.includes(fileType.mime);
        // Accept any MIME type starting with 'video/' OR audio containers that hold video
        // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
        const isVideo = fileType.mime.startsWith('video/') || ALLOWED_AUDIO_VIDEO_CONTAINERS.includes(fileType.mime);

        if (!isImage && !isVideo) {
            return {
                valid: false,
                message: `File type ${fileType.mime} is not allowed. Only images (jpg, png, gif, webp) and video files are permitted`,
                detectedType: fileType.mime
            };
        }

        return {
            valid: true,
            detectedType: fileType.mime
        };
    } catch (error: any) {
        // Log the error for debugging purposes
        console.error('File validation error:', error.message ?? error);
        return {
            valid: false,
            message: `Error validating file type: ${error.message ?? 'Unknown error'}`
        };
    }
}

/**
 * Validate file size based on file type
 */
export function validateFileSize(buffer: Buffer, detectedType: string): { valid: boolean; message?: string } {
    const fileSize = buffer.length;
    const isImage = ALLOWED_IMAGE_MAGIC_TYPES.includes(detectedType);
    // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
    const isVideo = detectedType.startsWith('video/') || ALLOWED_AUDIO_VIDEO_CONTAINERS.includes(detectedType);

    if (isImage && fileSize > MAX_IMAGE_SIZE) {
        return {
            valid: false,
            message: `Image file size exceeds maximum allowed size of ${MAX_IMAGE_SIZE / 1024 / 1024}MB`
        };
    }

    if (isVideo && fileSize > MAX_VIDEO_SIZE) {
        return {
            valid: false,
            message: `Video file size exceeds maximum allowed size of ${MAX_VIDEO_SIZE / 1024 / 1024}MB`
        };
    }

    return { valid: true };
}

/**
 * Complete file validation (type + size)
 */
export async function validateFile(buffer: Buffer): Promise<{ valid: boolean; message?: string; detectedType?: string }> {
    // First validate file type
    const typeValidation = await validateFileType(buffer);
    if (!typeValidation.valid) {
        return typeValidation;
    }

    // Then validate file size
    const sizeValidation = validateFileSize(buffer, typeValidation.detectedType!);
    if (!sizeValidation.valid) {
        return sizeValidation;
    }

    return {
        valid: true,
        detectedType: typeValidation.detectedType
    };
}
