const functions = require("firebase-functions");
const admin = require("firebase-admin");
const archiver = require("archiver");
const fs = require("fs");
const os = require("os");
const path = require("path");

admin.initializeApp();

const bucket = admin.storage().bucket();

exports.generateGroupZip = functions.https.onRequest(async (req, res) => {
    try {

        const groupId = req.body.unique_url; // required
        const folder_prefix = req.body.prefix;// required
        const zip_prefix = req.body.zip_file_prefix;// required

        if (!groupId) {
            return res.status(400).json({ error: "unique_url required" });
        }
        if (!folder_prefix) {
            return res.status(400).json({ error: "prefix required" });
        }
        if (!zip_prefix) {
            return res.status(400).json({ error: "zip_file_prefix required" });
        }

        const uniqueId = Date.now() + "_" + Math.floor(Math.random() * 10000);

        // ✅ SAFE: prefix controlled only by server
        const prefix = `${folder_prefix}${groupId}/`;

        // STEP 1: LIST ALL FILES IN FOLDER
        const [files] = await bucket.getFiles({
            prefix: prefix
        });

        if (!files.length) {
            return res.status(404).json({ error: "No files found" });
        }

        // STEP 2: CREATE ZIP
        const zipFileName = `${zip_prefix}${groupId}_${uniqueId}.zip`;
        const tempZipPath = path.join(os.tmpdir(), `${uniqueId}.zip`);

        const output = fs.createWriteStream(tempZipPath);
        const archive = archiver("zip", { zlib: { level: 9 } });

        archive.pipe(output);

        // collect temp files for cleanup
        const tempFiles = [];

        for (const file of files) {

            if (!file.name || file.name.endsWith("/")) continue;

            const tempFilePath = path.join(
                os.tmpdir(),
                `${Date.now()}_${path.basename(file.name)}`
            );

            await file.download({
                destination: tempFilePath
            });

            tempFiles.push(tempFilePath);

            archive.file(tempFilePath, {
                name: file.name.replace(`${folder_prefix}${groupId}/`, "")
            });
        }

        await archive.finalize();

        await new Promise(resolve => output.on("close", resolve));

        // STEP 3: UPLOAD ZIP
        await bucket.upload(tempZipPath, {
            destination: zipFileName,
            metadata: {
                contentType: "application/zip"
            }
        });

        // STEP 4: GENERATE SIGNED URL
        const file = bucket.file(zipFileName);

        // STEP 5: CLEAN TEMP FILES (IMPORTANT)
        try {
            fs.unlinkSync(tempZipPath);
            tempFiles.forEach(f => {
                if (fs.existsSync(f)) fs.unlinkSync(f);
            });
        } catch (e) {
            console.log("Cleanup error:", e.message);
        }

        return res.json({
            success: true,
            unique_id: uniqueId,
            zip_path: zipFileName
        });

    } catch (err) {
        console.error(err);
        return res.status(500).json({
            success: false,
            error: err.message
        });
    }
});