"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MediaFieldCrudManager = exports.SolidMediaType = void 0;
var SolidMediaType;
(function (SolidMediaType) {
    SolidMediaType["mediaSingle"] = "mediaSingle";
    SolidMediaType["mediaMultiple"] = "mediaMultiple";
})(SolidMediaType || (exports.SolidMediaType = SolidMediaType = {}));
const MIME_TO_MEDIA_TYPE = {
    'image/png': 'image',
    'image/jpeg': 'image',
    'image/jpg': 'image',
    'image/webp': 'image',
    'image/gif': 'image',
    'image/bmp': 'image',
    'image/tiff': 'image',
    'image/svg+xml': 'image',
    'image/heic': 'image',
    'image/heif': 'image',
    'audio/mpeg': 'audio',
    'audio/mp3': 'audio',
    'audio/wav': 'audio',
    'audio/x-wav': 'audio',
    'audio/webm': 'audio',
    'audio/ogg': 'audio',
    'audio/aac': 'audio',
    'audio/mp4': 'audio',
    'audio/x-m4a': 'audio',
    'audio/flac': 'audio',
    'video/mp4': 'video',
    'video/mpeg': 'video',
    'video/webm': 'video',
    'video/ogg': 'video',
    'video/quicktime': 'video',
    'video/x-msvideo': 'video',
    'video/x-matroska': 'video',
    'video/3gpp': 'video',
    'video/3gpp2': 'video',
    'application/pdf': 'pdf',
    'text/plain': 'file',
    'text/markdown': 'file',
    'application/json': 'file',
    'text/csv': 'file',
    'application/msword': 'file',
    'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'file',
    'application/vnd.ms-excel': 'file',
    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'file',
    'application/vnd.ms-powerpoint': 'file',
    'application/vnd.openxmlformats-officedocument.presentationml.presentation': 'file',
    'application/zip': 'file',
    'application/x-zip-compressed': 'file',
    'application/x-rar-compressed': 'file',
    'application/x-7z-compressed': 'file',
    'application/octet-stream': 'file',
};
const EXT_TO_MEDIA_TYPE = {
    png: 'image', jpg: 'image', jpeg: 'image', webp: 'image', gif: 'image', bmp: 'image', tiff: 'image', svg: 'image', heic: 'image', heif: 'image',
    mp3: 'audio', wav: 'audio', ogg: 'audio', aac: 'audio', m4a: 'audio', flac: 'audio',
    mp4: 'video', mov: 'video', avi: 'video', mkv: 'video', mpeg: 'video', mpg: 'video', '3gp': 'video', '3g2': 'video',
    pdf: 'file', txt: 'file', md: 'file', csv: 'file', json: 'file',
    doc: 'file', docx: 'file', xls: 'file', xlsx: 'file', ppt: 'file', pptx: 'file',
    zip: 'file', rar: 'file', '7z': 'file',
};
class MediaFieldCrudManager {
    constructor(options) {
        this.options = options;
    }
    resolveMediaType(mimetype, filename) {
        const mt = (mimetype || '').toLowerCase().trim();
        if (mt && MIME_TO_MEDIA_TYPE[mt]) {
            return MIME_TO_MEDIA_TYPE[mt];
        }
        if (mt.startsWith('image/'))
            return 'image';
        if (mt.startsWith('audio/'))
            return 'audio';
        if (mt.startsWith('video/'))
            return 'video';
        const ext = (filename || '').split('.').pop()?.toLowerCase();
        if (ext && EXT_TO_MEDIA_TYPE[ext]) {
            return EXT_TO_MEDIA_TYPE[ext];
        }
        return null;
    }
    validate(dto, files) {
        const fieldFiles = files.filter(file => file.fieldname === this.options.fieldName);
        return this.applyValidations(fieldFiles);
    }
    applyValidations(fieldFiles) {
        switch (this.options.type) {
            case SolidMediaType.mediaSingle:
                return this.validateMediaSingle(fieldFiles);
            case SolidMediaType.mediaMultiple:
                return this.validateMediaMultiple(fieldFiles);
            default:
                return [];
        }
    }
    validateMediaSingle(fieldFiles) {
        const errors = [];
        if (!this.options.isUpdate && this.options.required && fieldFiles.length === 0) {
            errors.push({
                field: this.options.fieldName,
                error: `${this.options.fieldName} is required`
            });
        }
        if (fieldFiles.length > 1) {
            errors.push({
                field: this.options.fieldName,
                error: `${this.options.fieldName} must be a single file`
            });
        }
        if (this.options.mediaMaxSizeKb) {
            for (let i = 0; i < fieldFiles.length; i++) {
                const fieldFile = fieldFiles[i];
                const fieldFileSizeInBytes = Math.ceil(fieldFile.size / 1024);
                if (fieldFileSizeInBytes > this.options.mediaMaxSizeKb) {
                    errors.push({
                        field: this.options.fieldName,
                        error: `${this.options.fieldName} with size ${fieldFileSizeInBytes} KB exceeds max size limit of ${this.options.mediaMaxSizeKb} KB`
                    });
                }
            }
        }
        if (this.options.mediaTypes && this.options.mediaTypes.length > 0) {
            const allowedFileTypes = this.options.mediaTypes;
            for (let i = 0; i < fieldFiles.length; i++) {
                const fieldFile = fieldFiles[i];
                const resolvedType = this.resolveMediaType(fieldFile.mimetype, fieldFile.originalname ?? fieldFile.filename ?? '');
                if (!resolvedType || !allowedFileTypes.includes(resolvedType)) {
                    errors.push({
                        field: this.options.fieldName,
                        error: `${this.options.fieldName} file type not allowed. ` +
                            `Allowed: ${allowedFileTypes.join(', ')}. ` +
                            `Received mimetype: ${fieldFile.mimetype}${resolvedType ? ` (mapped to ${resolvedType})` : ''}`
                    });
                }
            }
        }
        return errors;
    }
    validateMediaMultiple(fieldFiles) {
        const errors = [];
        if (!this.options.isUpdate && this.options.required && fieldFiles.length === 0) {
            errors.push({
                field: this.options.fieldName,
                error: `${this.options.fieldName} is required`
            });
        }
        return errors;
    }
    transformForCreate(dto) {
        return dto;
    }
}
exports.MediaFieldCrudManager = MediaFieldCrudManager;
//# sourceMappingURL=MediaFieldCrudManager.js.map