"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.uploadMultipleImages = exports.uploadSingleImage = void 0;
const crypto_1 = __importDefault(require("crypto"));
const promises_1 = __importDefault(require("fs/promises"));
const path_1 = __importDefault(require("path"));
const assets_1 = require("../config/assets");
const response_utils_1 = require("../utils/response.utils");
const maxImageBytes = 8 * 1024 * 1024;
const supportedImages = {
    'image/jpeg': '.jpg',
    'image/png': '.png',
    'image/webp': '.webp',
    'image/gif': '.gif',
    'image/avif': '.avif',
};
const saveImage = async (input) => {
    if (typeof input.dataUrl !== 'string')
        throw new Error('An image file is required.');
    const match = input.dataUrl.match(/^data:(image\/[a-z0-9.+-]+);base64,([a-zA-Z0-9+/=\r\n]+)$/);
    if (!match)
        throw new Error('The image payload is invalid.');
    const mimeType = match[1].toLowerCase();
    const extension = supportedImages[mimeType];
    if (!extension)
        throw new Error('Use a JPEG, PNG, WebP, GIF, or AVIF image.');
    const bytes = Buffer.from(match[2], 'base64');
    if (bytes.length === 0)
        throw new Error('The image file is empty.');
    if (bytes.length > maxImageBytes)
        throw new Error('The image must be 8 MB or smaller.');
    const storageKey = `uploads/books/${crypto_1.default.randomUUID()}${extension}`;
    const destination = path_1.default.join(assets_1.assetStorageDir, ...storageKey.split('/'));
    const temporary = `${destination}.part`;
    await promises_1.default.mkdir(path_1.default.dirname(destination), { recursive: true });
    await promises_1.default.writeFile(temporary, bytes, { flag: 'wx' });
    await promises_1.default.rename(temporary, destination);
    return {
        url: (0, assets_1.assetUrl)(storageKey),
        key: storageKey,
        fileName: typeof input.fileName === 'string' ? input.fileName : undefined,
        size: bytes.length,
        mimeType,
    };
};
const uploadSingleImage = async (req, res) => {
    try {
        const image = await saveImage(req.body ?? {});
        return (0, response_utils_1.sendSuccess)(res, 'Image uploaded to local storage successfully', image);
    }
    catch (error) {
        return (0, response_utils_1.sendError)(res, 'Image upload failed', error.message, 400);
    }
};
exports.uploadSingleImage = uploadSingleImage;
const uploadMultipleImages = async (req, res) => {
    try {
        const images = Array.isArray(req.body?.images) ? req.body.images : [];
        if (images.length === 0)
            throw new Error('At least one image is required.');
        if (images.length > 8)
            throw new Error('Upload no more than 8 images at once.');
        const saved = await Promise.all(images.map((image) => saveImage(image)));
        return (0, response_utils_1.sendSuccess)(res, 'Images uploaded to local storage successfully', {
            images: saved,
            urls: saved.map((image) => image.url),
        });
    }
    catch (error) {
        return (0, response_utils_1.sendError)(res, 'Multiple images upload failed', error.message, 400);
    }
};
exports.uploadMultipleImages = uploadMultipleImages;
//# sourceMappingURL=upload.controller.js.map