"use strict";

var q = require("q");
var moment = require('moment');
var dateUtil = require('../../utils/UtilDate');
var UtilDocumentId = require('../../../shared/utils/UtilDocumentId');
var logger = require('../../utils/Logger').loggers.get('db');

function getCreatedBy(userId) {
    var deferred = q.defer();
    var validValue;

    if (userId) {
        var accountDataService = require('../dataServices/AccountService');

        accountDataService.getAccountById(userId)
        .then(function successFunc(user) {
            if (user) {
                var summaryName = "";
                if (user.systemHeader && user.systemHeader.summaryName) {
                        summaryName = user.systemHeader.summaryName;
                }

                validValue = {
                    "documentId": user.documentId,
                    "name": summaryName
                };

                deferred.resolve(validValue);
            }
        }, function errorFunc(err) {
            logger.error("Error getting account for userId: " + userId);
            validValue = null;
            deferred.resolve(validValue);
        });
    }
    return deferred.promise;
}

function getValidId(value) {
    var validValue;

    if (!value) {
        // default the value
        logger.warn("No dataId provided - generarting new dataId");
        validValue = UtilDocumentId.generateId();
    } else {
        // use existing value
        validValue = value;
    }

    return validValue;
}

function getValidDate(value) {
    var validValue;

    if (!value) {
        // default the value
        logger.warn("No date provided - defaulting to current date.");
        validValue = new Date();
    } else {
        if(dateUtil.isDate(value)) {
            // use existing value
            validValue = value;
        } else {
            // attempt to convert and use supplied value, otherwise default the value

            // turning on strict parsing with the true at the end of the moment() call
            var date = moment(value, ["DD/MM/YYYY hh:mm a", "DD/MM/YYYY", "hh:mm a", moment.ISO_8601], true);
            if (date.isValid()) {
                // use existing value (converted)
                validValue = date.toDate();
            } else {
                // default the value
                logger.warn("Unable to convert value (" + value + ") to date. Defaulting to current date.");
                validValue = new Date();
            }
        }
    }

    return validValue;
}

/**
 *
 * @param field
 * @param document
 * @returns {deferred.promise|*}
 */
module.exports.preProcess = function(field, document, userId) {
    var deferred = q.defer();

    var commentField;
    var voteField;

    if (document[field.name]) {
        var noteCommentField = document[field.name];

        // Temporarily handle both old and new noteComment structures
        // while integration transitions to new structure
        var oldStructure = false;
        if (noteCommentField.note) {
            oldStructure = true;
        }

        if (oldStructure) {
            // process old noteComment structure
            logger.warn('Processing old noteComment structure');

            // after transition complete reinstate error handling
            //var errMsg = field.componentName + " field named " + field.name +
            //    " has invalid value \"" + noteCommentField + "\"";
            //logger.error("Preprocessing Failure : " + errMsg);
            //deferred.reject(errMsg);

            var totalNotes = noteCommentField.note.length;
            logger.info('Processing notes of length ' + totalNotes);
            if (totalNotes > 0) {
                for (var i = 0; i < totalNotes; i++) {
                    if (!noteCommentField.note[i].time)
                        noteCommentField.note[i].time = new Date();

                    if (noteCommentField.note[i].comments) {
                        var totalComments = noteCommentField.note[i].comments.length;

                        for (var j = 0; j < totalComments; j++) {
                            if (!noteCommentField.note[i].comments[j].time) {
                                noteCommentField.note[i].comments[j].time = new Date();
                            }
                        }
                    }
                }
            }
            deferred.resolve(document);
        } else {
            // process new noteComment structure
            var totalNotes = noteCommentField.length;
            var counter = 1;

            if (totalNotes > 0) {
                getCreatedBy(userId)
                .then(function successFunc(createdBy) {

                    logger.info('Processing notes array of length ' + totalNotes);
                    noteCommentField.forEach(function (noteValue) {
                        logger.debug("Processing note "+counter+"/"+totalNotes);
                        counter = counter +1;
                        noteValue.dataId = getValidId(noteValue.dataId);
                        noteValue.createdDate = getValidDate(noteValue.createdDate);
                        if (!noteValue.createdBy && createdBy) noteValue.createdBy = createdBy;

                        if (typeof noteValue.comments !== "undefined") {
                             if (noteValue.comments.length > 0) {
                                commentField = noteValue.comments;
                                commentField.forEach(function (commentValue) {
                                    commentValue.dataId = getValidId(commentValue.dataId);
                                    commentValue.createdDate = getValidDate(commentValue.createdDate);
                                    if (!commentValue.createdBy && createdBy) commentValue.createdBy = createdBy;
                                });
                            }
                        }

                        if (typeof noteValue.votes !== "undefined") {
                            if (noteValue.votes.length > 0) {
                                voteField = noteValue.votes;
                                voteField.forEach(function (voteValue) {
                                    voteValue.dataId = getValidId(voteValue.dataId);
                                    voteValue.createdDate = getValidDate(voteValue.createdDate);
                                    if (!voteValue.createdBy && createdBy) voteValue.createdBy = createdBy;
                                });
                            }
                        }
                    });
                    deferred.resolve(document);
                }, function errorFunc(err) {
                    logger.error("error in function getCreatedBy - " + err);
                    deferred.resolve(document);
                });
            } else {
                deferred.resolve(document);
            }
        }
    } else {
        deferred.resolve(document);
    }
    return deferred.promise;

};
