// Load environment variables from .env file
require('dotenv').config({
    path: '../../../.env'
});

// Import required modules
const logger = require('../../../logger');
const Minio = require("minio"),
    MongoClient = require('mongodb').MongoClient,
    path = require('path');

// Get details from environment variables for MinIO
let endPoint = process.env.minioEndPoint;
let port = parseInt(process.env.minioPort);
let useSSL = true;
const accessKey = process.env.minioAccessKey;
const secretKey = process.env.miniosecretKey;

// Bucket name for YONO
const bucketName = process.env.exportsCsvBckt;

// Get database details from environment variables
let dburlParts = process.env.productionUrl.split("/")
const dbname = dburlParts[dburlParts.length - 1]

let database

// Create a MinIO client
let minioClient = new Minio.Client({
    endPoint: endPoint,
    port: port,
    useSSL: useSSL,
    accessKey: accessKey,
    secretKey: secretKey,
});

// Connect to MongoDB
MongoClient.connect(process.env.productionUrl, {
    useUnifiedTopology: true
}, function(err, db) {
    if (err) throw err;
    database = db.db(dbname);
    logger.info(`Mongo DB connected`);

    // Call the function after the database is connected
    asyncCall();
});

// Function to return all app IDs
let getAllAppids = async () => {
    return new Promise(async (resolve, reject) => {
        let appids = [];
        // Get all collections from the database
        let collections = await database.listCollections().toArray();
        // Filter exportjobs collections
        for (let collection of collections) {
            if (collection.name.startsWith('exportjobs_'))
                appids.push(collection.name.substr(11));
        }
        resolve(appids);
    });
};

// Function to download files from MinIO
function downloadFilesFromMinio(appId) {
    logger.info(`🚀 ~ file: cronDownloadMinio.js:22 ~ downloadFilesFromMinio Cron now running For Appid ${appId}`);
    database.collection("exportjobs_" + appId).find({
        "status": "processed"
    }).toArray(function(err, exportResult) {
        if (err || exportResult.length == 0) {
            logger.error(`🚀 ~ file: cronDownloadMinio.js:28 ~ err${err}`);
        } else {
            exportResult.forEach(element => {
                if (!element.downloaded || element.downloaded == false) {
                    logger.info(`🚀 ~ file: cronDownloadMinio.js:31 ~ element.exportjobentityurl${element.exportjobentityurl}`);
                    logger.info(`🚀 ~ file: cronDownloadMinio.js:31 ~ element.filename", ${element.filename}`);
                    let filenameInTheBucket = element.exportjobentityurl;
                    let pathName = path.join(__dirname + "../../../exports/");
                    pathName = path.join(pathName + filenameInTheBucket);
                    minioClient.fGetObject(bucketName, filenameInTheBucket, pathName, function(err) {
                        if (err) {
                            logger.error(`🚀 Failed! while downloading file In getObject${err}`);
                        } else {
                            logger.info(`🚀 successfully Downloaded file ${filenameInTheBucket}`);
                            database.collection("exportjobs_" + appId).update({
                                "filename": element.filename
                            }, {
                                $set: {
                                    "downloaded": true
                                }
                            }, function(err, result) {
                                if (err) {
                                    logger.error(`🚀 ~ file: cronDownloadMinio.js:93 ~ err Updating in db: ${err}`);
                                }
                            });
                        }
                    });
                } else {
                    logger.info(`🚀 file Is Already Downloaded: ${element.exportjobentityurl}`);
                }
            });
        }
    });
}

// Function to sleep for a specified number of milliseconds
function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

// Main function to call the async functions
async function asyncCall() {
    let appids = await getAllAppids();
    while (1) {
        for (let appid of appids) {
            downloadFilesFromMinio(appid);
        }
        await sleep(3000);
    }
}
