var tabsInteractionModule = (function () {
    var self,
        _debug = false,
        _events = {};

    /**
     * Отправка сообщения дебага в консоль
     * @param data данные для отправки в консоль
     * @param type {string} тип сообщения - info, error, если undefined, то стандартный тип
     * @private
     */
    var _sendDebug = function (data, type) {
        if (!_debug) {
            return;
        }

        switch (type) {
            case 'info':
                console.info(data);
                break;
            case 'error':
                console.error(data);
                break;
            default:
                console.log(data);
                break
        }
    };

    /**
     * Установка внутренних событий
     *
     * @private
     */
    var _setEvents = function () {
        $(window).on('storage', _update);
    };

    /**
     * Установить выполнение всех функций привязанных событий по интервалу на главной вкладке
     * @private
     */
    var _setMainIntervals = function () {
        _sendDebug('Set new main intervals!', 'info');
        var eventsName = Object.keys(_events);
        for (var i = 0; i < eventsName.length; i++) {
            _setInterval(eventsName[i]);
        }
    };

    /**
     * Установить выполнение функции события по интервалу
     *
     * @param eventName {string}
     * @private
     */
    var _setInterval = function (eventName) {
        var event = _events[eventName];

        if (_events[eventName].intervalId) {
            return;
        }

        if (event.timeout > 0) {
            _events[eventName].intervalId = setInterval(event.onMain, event.timeout);
        }
    };

    /**
     * Очистка интервалов всех привязанных событий
     *
     * @private
     */
    var _clearIntervals = function () {
        _sendDebug('Interval is cleared', 'info');
        var eventNames = Object.keys(_events);
        for (var i = 0; i < eventNames.length; i++) {
            var key = eventNames[i];
            clearInterval(_events[key].intervalId);
        }
    };

    /**
     * Обновить данные второстепенных вкладок
     *
     * @param event {Object}
     * @private
     */
    var _update = function (event) {
        if (self.tabs.isMainTab()) {
            return;
        }

        if (_events.hasOwnProperty(event.originalEvent.key)) {
            _events[event.originalEvent.key].onSecond(JSON.parse(JSON.parse(event.originalEvent.newValue).value).value);
            _sendDebug('updated', 'info');
        }
    };

    /**
     * Сгенерировать название события для хранения в LocalStorage
     * @param name {string}
     * @returns {string}
     * @private
     */
    var _getEventName = function (name) {
        return 'event-' + name;
    };

    return {
        init: function () {
            self = this;
            self.tabs.setTabId();
            self.tabs.setIntervals();
            _setEvents();
        },
        /**
         * Запустить триггер события обновления вкладок
         *
         * @param {string} eventName - название события
         * @param {object} value - данные для передачи другим вкладкам
         */
        updateTabsEvent: function (eventName, value) {
            eventName = _getEventName(eventName);
            var data = {
                value: value,
                date: Date.now()
            };

            self.storage.set(eventName, JSON.stringify(data));
        },
        update: function (e) {
            _update(e);
        },
        addListener: function (eventName, callbackOnSecond) {
            self.setTimeoutFunction(eventName, null, callbackOnSecond, 0);
        },
        setTimeoutFunction: function (eventName, callbackOnMain, callbackOnSecond, timeout) {
            eventName = _getEventName(eventName);
            _events[eventName] = {
                onMain: callbackOnMain,
                onSecond: callbackOnSecond,
                timeout: timeout,
                intervalId: null
            };
        },
        tabs: (function () {
            var _tabs,
                _tabId,
                _mainTabId = null;

            var STORAGE_TABS_ID = 'prd-tabs-ids';

            var _clearOldTabs = function () {
                var keys = Object.keys(_tabs);
                var currentDate = new Date().getTime();
                var wasDeleted = false;
                for (var i = 0; i < keys.length; i++) {
                    var tabId = keys[i];
                    if (_tabs[tabId].time < currentDate - 2000) {
                        delete _tabs[tabId];
                        wasDeleted = true;
                        _sendDebug('too old tab - ' + tabId, 'info');
                    }
                }

                if (wasDeleted) {
                    self.storage.set(STORAGE_TABS_ID, _tabs);
                }
            };

            var _sendAliveMessage = function () {
                _tabs[_tabId] = {time: new Date().getTime()};
                self.storage.set(STORAGE_TABS_ID, _tabs);
                //_sendDebug('Im alive');
            };
            var _setTabs = function () {
                var tabs = self.storage.get(STORAGE_TABS_ID);

                // _sendDebug('got new tabs!', 'info');

                _tabs = tabs.value == null ? {} : tabs.value;

                if (_mainTabId === null || _tabs.hasOwnProperty(_mainTabId) === false) {
                    _mainTabId = Math.min.apply(Math, Object.keys(_tabs));

                    if (self.tabs.isMainTab()) {
                        _sendDebug('Is Main Tab', 'info');
                        _setMainIntervals();
                    } else {
                        _clearIntervals();
                    }

                    _sendDebug('set new Main Tab ' + _mainTabId, 'info');
                }
            };

            var _intervalTabPoll = function () {
                _setTabs();
                _clearOldTabs();
                _sendAliveMessage();
            };

            return {
                /**
                 * Установить идентификатор для вкладки
                 */
                setTabId: function () {
                    var date = new Date();
                    _setTabs();
                    _tabId = date.getTime();
                    _tabs[_tabId] = {time: date.getTime()}
                },
                /**
                 * установка интервала опроса вкладок
                 */
                setIntervals: function () {
                    setInterval(_intervalTabPoll, 1000);
                },
                /**
                 * Получить идентификатор вкладки
                 * @returns {string}
                 */
                getTabId: function () {
                    return _tabId;
                },
                /**
                 * Проверка, является ли эта влкадка главной
                 *
                 * @returns {boolean}
                 */
                isMainTab: function () {
                    return _mainTabId === _tabId;
                }
            }
        })(),
        /**
         * Управление локальным хранилищем
         */
        storage: (function () {
            return {
                set: function (name, value) {
                    var data = {
                        value: value,
                        date: Date.now()
                    };

                    localStorage.setItem(name, JSON.stringify(data));
                },
                get: function (name) {
                    var value = localStorage.getItem(name);
                    if (!value) {
                        return {value: null, time: null};
                    }

                    return JSON.parse(localStorage.getItem(name));
                }
            }
        })()
    }
})();

tabsInteractionModule.init();