/**
 * @typedef {Object} Events
 * @property {Events.publish} publish Publish an event
 * @property {Events.subscribe} subscribe Subscribe to an event
 * @property {Events.unsubscribe} unsubscribe Unsubscribe from an event
 */
/**
 * @callback Events.publish
 * @param {String} eventName The name of the event to publish.
 * @param {Array} parameters Additional parameters to apply to subscribing callbacks
 *
 * @example Publish a custom event. The first parameter should be the instance of the plugin.
 * The second entry in the parameter list can be used to pass additional information to the callback.
 *
 * NOTE: This is only a convention and not required.
 *
 * ```
 * Events.publish('easytemplate/Plugin/MyPlugin/onMyCustomEvent', [this, {foo: 'bar'}]);
 * ```
 */
/**
 * @callback Events.subscribe
 * @param {String} eventName The name of the event to subscribe to.
 * @param {Function} callback Event Callback
 *
 * @example Subscribe to the onSetHeight event of the etShortenToPlugin. The first parameter of the callback is
 * generally the Event and the second one the instance of the plugin.
 *
 * ```
 * Events.subscribe('easytemplate/Plugin/etShortenToPlugin/onSetHeight', function (event, plugin, {maxHeight}) {
 *      Logger.debug(
 *          'Callback for easytemplate/Plugin/etShortenToPlugin/onSetHeight', [this, event, plugin, maxHeight]
 *      );
 * });
 * ```
 */
/**
 * @callback Events.unsubscribe
 * @param {String} eventName The name of the event to unsubscribe from.
 * @param {Function} callback Event Callback
 */

/**
 * @typedef {Object} Logger
 * @property {Logger.debug} debug Log a debug message
 * @property {Logger.error} error Log an error message
 * @property {Logger.info} info Log an info message
 */
/**
 * @callback Logger.debug
 * @param {String} message Message to log
 * @param {any} extra Extra parameter to log
 */
/**
 * @callback Logger.info
 * @param {String} message Message to log
 * @param {any} extra Extra parameter to log
 */
/**
 * @callback Logger.error
 * @param {String} message Message to log
 * @param {any} extra Extra parameter to log
 */

(function($, document, window, viewports) {
    'use strict';

    /**
     * @class
     * @public
     */
    const Logger = {
        /**
         * Log a debug message
         * @param {String} message Message to log
         * @param {any} extra Extra parameter to log
         */
        debug: function(message, extra) {
            if (!window.easytemplate || !window.easytemplate.debug) {
                return;
            }

            if (extra) {
                console.log(
                    '%c [ET360]: ' + message, 'padding: 3px 0; color: #50e590; background: #17384c',
                    extra
                );

                return;
            }

            console.log(
                '%c [ET360]: ' + message, 'padding: 3px 0; color: #50e590; background: #17384c'
            );
        },

        /**
         * Log an info message
         * @param {String} message Message to log
         * @param {any} extra Extra parameter to log
         */
        info: function(message, extra) {
            if (!window.easytemplate || !window.easytemplate.debug) {
                return;
            }

            if (extra) {
                console.info(
                    '%c [ET360]: ' + message, 'padding: 3px 0; color: #50e590; background: #17384c',
                    extra
                );

                return;
            }

            console.info(
                '%c [ET360]: ' + message, 'padding: 3px 0; color: #50e590; background: #17384c'
            );
        },

        /**
         * Log an errormessage
         * @param {String} message Message to log
         * @param {any} extra Extra parameter to log
         */
        error: function(message, extra) {
            if (extra) {
                console.error('[ET360]: ' + message, extra);
                return;
            }

            console.error('[ET360]: ' + message);
        }
    };

    /**
     * @class
     * @public
     */
    const Events = {
        /**
         * Publish an event
         * @param {String} eventName The name of the event to publish.
         * @param {Array} parameters Additional parameters to apply to subscribing callbacks
         */
        publish: function(eventName, parameters) {
            Logger.debug('Publish Event "' + eventName + '" with Parameters: ', parameters);
            $(document).trigger(eventName, parameters);
        },

        /**
         * Subscribe to an event
         * @param {String} eventName The name of the event to subscribe to.
         * @param {Function} callback Event Callback
         */
        subscribe: function(eventName, callback) {
            Logger.debug('Subscribe to Event "' + eventName);
            $(document).on(eventName, callback);
        },

        /**
         * Unsubscribe from an event
         * @param {String} eventName The name of the event to unsubscribe from.
         * @param {Function} callback Event Callback
         */
        unsubscribe: function(eventName, callback) {
            Logger.debug('Unsubscribe from Event "' + eventName);
            $(document).off(eventName, callback);
        },
    };

    // Expose to global namespace
    window.easytemplate = window.easytemplate || {};
    window.easytemplate.Logger = Logger;
    window.easytemplate.Events = Events;
})(jQuery, document, window, ResponsiveBootstrapToolkit);