/* --------------------------------------------------------------
 info_box.js 2019-07-12
 Gambio GmbH
 http://www.gambio.de
 Copyright (c) 2019 Gambio GmbH
 Released under the GNU General Public License (Version 2)
 [http://www.gnu.org/licenses/gpl-2.0.html]
 --------------------------------------------------------------
 */

jse.libs.info_box = jse.libs.info_box || {};

/**
 * ## Info Box Messages Library
 *
 * This module provides an API to the new admin layout pages info box.
 *
 * @module Admin/Libs/info_box
 * @exports jse.libs.info_box
 */
(function (exports) {

    'use strict';

    // Admin info box element selector.
    const infoboxSelector = '.info-box';

    /**
     * Performs an ajax request to the server.
     *
     * @param {String} action URL action part.
     * @param {String} method HTTP request method.
     * @param {Object} data   Request data.
     *
     * @return {Deferred|Promise}
     *
     * @private
     */
    function _performRequest(action, method, data) {
        const URL_BASE = 'admin.php?do=AdminInfoBoxAjax';

        // AJAX request options.
        const ajaxOptions = {
            url: URL_BASE + action,
            dataType: 'json',
            data,
            method
        };

        // Returns deferred object.
        return $.ajax(ajaxOptions);
    }

    // Message status.
    exports.STATUS_NEW = 'new';
    exports.STATUS_READ = 'read';
    exports.STATUS_HIDDEN = 'hidden';
    exports.STATUS_DELETED = 'deleted';

    // Message types.
    exports.TYPE_INFO = 'info';
    exports.TYPE_WARNING = 'warning';
    exports.TYPE_SUCCESS = 'success';

    // Message visibility.
    exports.VISIBILITY_ALWAYS_ON = 'alwayson';
    exports.VISIBILITY_HIDEABLE = 'hideable';
    exports.VISIBILITY_REMOVABLE = 'removable';

    // Admin action success message identifier prefix.
    exports.SUCCESS_MSG_IDENTIFIER_PREFIX = 'adminActionSuccess-';

    /**
     * Returns the messages from the server (visible only).
     *
     * @return {Promise}
     */
    exports.getMessages = function () {
        return _performRequest('/GetAllMessages', 'GET');
    };

    /**
     * Sets the status of a message.
     *
     * @param {Number} id Message ID.
     * @param {String} status Message status to set ('new', 'read', 'hidden', 'deleted').
     *
     * @return {Promise}
     */
    exports.setStatus = function (id, status) {
        // Valid message status.
        const validStatus = [exports.STATUS_NEW, exports.STATUS_READ, exports.STATUS_HIDDEN, exports.STATUS_DELETED];

        // Check arguments.
        if (!id || !status) {
            throw new Error('Missing ID or status');
        } else if (validStatus.indexOf(status) === -1) {
            throw new Error('Invalid status provided');
        }

        return _performRequest('/SetMessageStatus', 'GET', {id, status})
    };

    /**
     * Deletes a message.
     *
     * @param {Number} id Message ID.
     *
     * @return {Promise}
     */
    exports.deleteById = function (id) {
        if (!id) {
            throw new Error('Missing ID');
        }

        return _performRequest('/DeleteById', 'GET', {id});
    };

    /**
     * Deletes a message by source.
     *
     * @param {String} source Message source.
     *
     * @return {Promise}
     */
    exports.deleteBySource = function (source) {
        if (!source) {
            throw new Error('Missing source');
        }

        return _performRequest('/DeleteBySource', 'GET', {source});
    };

    /**
     * Deletes a messages by the identifier.
     *
     * @param {String} identifier Message identifier.
     *
     * @return {Promise}
     */
    exports.deleteByIdentifier = function (identifier) {
        if (!identifier) {
            throw new Error('Missing identifier');
        }

        return _performRequest('/DeleteByIdentifier', 'GET', {identifier});
    };

    /**
     * Reactivates the messages.
     * @return {Promise}
     * @static
     */
    exports.Reactivates = function () {
        return _performRequest('/ReactivateMessages', 'GET');
    };

    /**
     * Saves a new message.
     *
     * @param {Object} message The new message to save.
     *
     * @example
     * jse.libs.info_box.addMessage({
     *   source: 'ajax',
     *   identifier: 'asdas',
     *   status: 'new',
     *   type: 'success',
     *   visibility: 'removable',
     *   customerId: 0,
     *   headline: 'My Headline',
     *   buttonLabel: 'asdas',
     *   buttonLink: 'http://google.com', // optional
     *	 buttonLink: 'customers.php', // optional
     *   message: 'Hallo!',
     * });
     *
     * @return {Promise}
     */
    exports.addMessage = function (message) {
        if (!message) {
            throw new Error('Missing message object');
        } else if (!message.source) {
            throw new Error('Missing source');
        } else if (!message.identifier) {
            message.identifier = 'generated-' + Date.now();
        } else if (!message.status || [
            exports.STATUS_NEW, exports.STATUS_READ, exports.STATUS_HIDDEN,
            exports.STATUS_DELETED
        ].indexOf(message.status) === -1) {
            throw new Error('Missing or invalid status');
        } else if (!message.type || [
            exports.TYPE_INFO, exports.TYPE_WARNING,
            exports.TYPE_SUCCESS
        ].indexOf(message.type) === -1) {
            throw new Error('Missing or invalid type');
        } else if (!message.visibility || [
            exports.VISIBILITY_ALWAYS_ON, exports.VISIBILITY_HIDEABLE,
            exports.VISIBILITY_REMOVABLE
        ].indexOf(message.visibility) === -1) {
            throw new Error('Missing or invalid visibility');
        } else if (typeof message.customerId === 'undefined') {
            throw new Error('Missing customer ID');
        } else if (!message.message) {
            throw new Error('Missing message');
        } else if (!message.headline) {
            throw new Error('Missing headline');
        } else if (!message.message) {
            throw new Error('Missing message');
        }

        return _performRequest('/AddMessage', 'GET', message);
    };

    /**
     * Adds a success message to the admin info box.
     *
     * @param {String} [message] Message to show.
     * @param {Boolean} [skipRefresh = false] Refresh the admin info box to show the message?
     */
    exports.addSuccessMessage = function (message, skipRefresh = false) {
        // Add message.
        const request = _performRequest('/AddSuccessMessage', 'GET', message ? {message} : {});

        // Optionally refresh the admin info box to show the message.
        if (!skipRefresh) {
            request.done(() => $(infoboxSelector).trigger('refresh:messages'));
        }
    };
}(jse.libs.info_box));