'use strict';

var mailHelper = require('../email/EmailHelper');
var passwordHelper = require('../account/PasswordHelper');
var accountDataService = require('../database/dataServices/AccountService');
var UtilError = require("../utils/UtilError");

/* accounts methods */
exports.findOne = function(id) {
    return accountDataService.getAccountById(id);
};

exports.findOneByPublicURL = function(accountPublicURL) {
    return accountDataService.getAccountByPublicURL(accountPublicURL);
};

exports.doLocalLogin = async function (email, password) {
    try {
        const account = await accountDataService.getAccount(email, true, { value: password, hashed: false });
        const accountControl = await accountDataService.getAccountControlDocument(account.documentId);

        if (accountControl.resetPasswordOnLogin) {
            let hash = accountControl.resetPassHash;
            // create password reset document
            if (!hash) {
                const resetPassDoc = await accountDataService.createPasswordResetDocument(account.email);
                hash = resetPassDoc.pass;
            }

            // pass email and hash needed to reset password
            let err = new UtilError.PasswordResetRequired();
            err.resetPassRequirements = {
                email: account.email,
                hash: hash
            };

            throw err;
        }

        await accountDataService.updateLoginDocument(account, true);

        return { account, accountControl };
    } catch (err) {
        const account = await accountDataService.getAccount(email);
        if (account) {
            await accountDataService.updateLoginDocument(account, false);
        }

        throw err;
    }
};

exports.doEmailLogin = function (email, callback) {
    accountDataService.getAccount(email, true)
        .then(function successFunc(account) {
            if (account) {
                callback(null, account);
            } else {
                callback(new Error(`No account registered for '${email}'!`));
            }
        }, function errorFunc(err) {
                if (err.message === 'Account not found.') {
                    callback(new Error(`No account registered for '${email}'!`));
                } else {
                    callback(err);
                }
        });
};

exports.autoLocalLogin = function (email, hash, callback) {
    accountDataService.getAccount(email, true, hash)
        .then(function successFunc(account) {
            if (account) {
                callback(account);
            } else {
                callback(null);
            }
        }, function errorFunc(err) {
            callback(null);
        });
};

exports.requireSocialAccount = function (user, queries, callback) {
    DataService.findAll(queries, user.documentId)
        .then(function successFunc(item) {
            if (item && item.length > 0) {
                callback(item[0] || item);
            } else {
                DataService.insert(user)
                    .then(function successFunc(data) {
                        callback(data);
                    }, function errorFunc(error) {
                        callback(null);
                    });
            }
        }, function errorFunc(err) {
            callback(null);
        });
};

exports.activateAccount = function (token, callback) {

    Promise.resolve().then(function () {
        return accountDataService.activateAccount(token);
    }).then(function(account){
        callback(null, account);
    }).catch(function (err) {
        logger.error("Failed to activate account: " + email);
        logger.error(err);
        callback(err);
    });

};

exports.sendResetLink = function (requestObject, fullDomainUrl, callback) {
    accountDataService.createPasswordResetDocument(requestObject)
        .then(function successFunc(account) {
            if (account) {
                mailHelper.dispatchResetPasswordLink(account, fullDomainUrl, function (error) {
                    callback(error);
                });
            } else {
                callback(new UtilError.AccountNotFoundError());
            }
        }, function errorFunc(err) {
            callback(err);
        });
};

exports.resetPassword = function (email, hash, newPass, callback) {

    accountDataService.resetPassword(email, hash, newPass).then(function(){
        callback(null, "ok");
    }).catch(function(err){
        var errMsg = "Error resetting password: " + err.message ? err.message : err;
        logger.error(errMsg);
        callback(new Error(errMsg));
    });

};

exports.doApiKeyLogin = function(apiKey, clientIp, callback) {
    logger.info("Connecting from: " + clientIp);
    accountDataService.getAccountByApiKey(apiKey, [clientIp]).then(function(user) {
        callback(null, user);
    }, function error(err) {
        logger.error("Failed connection from: " + clientIp + " " + err);
        callback(err);
    });
};

exports.getAccountControlDocument = function(userId){
    return accountDataService.getAccountControlDocument(userId);
};

exports.getAccountGroupConfigDocument = function(userId){
  return accountDataService.getAccountGroupConfigDocument(userId);
};
