'use strict';

var q = require("q");
var MongoConnection = require('./MongoConnection');
var logger = require('../../../utils/Logger').loggers.get('db');
var SharedConstants = require('../../../../shared/constants/SharedConstants');
/*
* All functions in this service will retrieve data with no authenticated user or user keys...
* */

function getCurrentScheduledDocuments() {
    var currentDate = new Date();

    var query = {
        "nextRunDate": {"$lte": currentDate },
        "systemHeader.systemType": SharedConstants.SYSTEM_TYPE_SCHEDULE,
        "systemHeader.currentVersion": true,
        "rulesetRel": { "$exists": true },
        "scheduleActive": true
    };

    return new Promise((resolve, reject) => {
        MongoConnection.getCollection((err, collection) => {
            if (err) {
                var errorMsg = "Error creating collection to getRuleSetId: " + err;
                reject(new Error(errorMsg));
            } else {
                collection.find(query).toArray((err, data) => {
                    if (err) {
                        reject(err);
                    } else {
                        resolve(data);
                    }
                });
            }
        });
    });
}

function markSystemActionDone(systemAction, statusDescription) {
    logger.info('Marking System Action Document... ');
    var deferred = q.defer();

    if (systemAction) {
        const newDate = new Date();
        const updates = {
            "actionedDate": newDate,
            statusDescription
        };

        MongoConnection.getCollection(function (err, collection) {
            if (err) {
                const errorMsg = "Error creating collection to markSystemActionDone: " + err;
                logger.error(errorMsg);
                deferred.reject(new Error(errorMsg));
            } else {
                collection.updateOne(
                    {
                        'documentId': systemAction.documentId,
                        'systemHeader.currentVersion': true
                    },
                    {
                        $set: updates
                    }
                ).then(() => {
                    logger.info(`System Action: ${systemAction.documentId} marked done. statusDescription: ${statusDescription}`);
                    deferred.resolve();
                }).catch(error => {
                    const errorMsg = 'Error on markSystemActionDone: ' + error.message;
                    logger.info(errorMsg);
                    deferred.reject(new Error(errorMsg));
                });
            }
        });
    } else {
        deferred.reject(new Error('No system action document provided.'));
    }

    return deferred.promise;
}

function getUnactionedSystemActions() {
    var dueDate = new Date();

    // get system actions that are unactioned and have reached the due date
    var query = {"actionedDate": null,
        "$and": [
            {"dueDate": {"$lte": dueDate}},
            {"dueDate": {"$type": "date"}}
        ],
        "systemHeader.systemType": SharedConstants.SYSTEM_TYPE_SYSTEM_ACTION,
        "systemHeader.deleted": null,
        "systemHeader.currentVersion": true,
        "userId": {"$exists": true},
        "cancelledBool": {"$ne": true}};

    var deferred = q.defer();

    MongoConnection.getCollection(function (err, collection) {
        if (err) {
            var errorMsg = "Error creating collection to getRuleSetId: " + err;
            logger.error(errorMsg);
            deferred.reject(new Error(errorMsg));
        } else {
            var cursor = collection.find(query);
            deferred.resolve(cursor);
        }
    });

    return deferred.promise;
}

const processUnactionedSystemActions = (systemActionProcessingFunc) => {
    return new Promise(function (resolve, reject) {
        getUnactionedSystemActions().then((cursor) => {
            function processItem(err, item) {
                if(item === null) {
                    resolve();
                } else {
                    systemActionProcessingFunc(item).then(function(){
                        cursor.next(processItem);
                    }, function(err){
                        cursor.close();
                        reject(err);
                    });
                }
            }

            cursor.next(processItem);
        }).catch((err => {
            reject(err);
        }));
    });
};

const getIncludeDocsQuery = (includeNames) =>{

    let statement = { "systemHeader.systemType" :  SharedConstants.SYSTEM_TYPE_RULESET_INCLUDE };
    if (includeNames && includeNames.length > 0) {
        statement.name = {$in: includeNames};
    }

    return  statement;

};

const getRuleSetIdQuery = (event, templateId) => {

    let statement = {
        "systemHeader.systemType" :  SharedConstants.SYSTEM_TYPE_RULESET,
        "event" :  event,
        "template.documentId" :  templateId
    };

    return statement;

};

const getRuleSetIdByNameQuery = (name) =>{
    let statement = {
        "name": name,
        "systemHeader.systemType": SharedConstants.SYSTEM_TYPE_RULESET
    };

    return statement;

};

////////////////////////////////s////
// public api
module.exports = {

    getUnactionedSystemActions: getUnactionedSystemActions,

    processUnactionedSystemActions,

    getCurrentScheduledDocuments: getCurrentScheduledDocuments,

    getIncludeDocsQuery: getIncludeDocsQuery,

    getRuleSetIdQuery: getRuleSetIdQuery,

    markSystemActionDone,

    getRuleSetIdByNameQuery
};

