(function () {
    'use strict';

    var iContentLoader = null

    // Helpers

    // @param {string} url
    // @param {object} params
    function load(url, params) {
        // проверка залогинен ли пользователь
        if (BEM.blocks['i-global'].param('login').length === 0) {
            // если нет, то показываем домик
            Lego.block['b-domik_type_popup'].login();
            return null;
        }

        var query = '';
        try {
            var needToAppendCaptchaQuery = ((window && window.location.hash) || '').indexOf('show_me_captcha_please') !== -1;

            if (needToAppendCaptchaQuery) {
                var isEmptyQueryStringInUrl = (url || '').indexOf('?') === -1;

                query = (isEmptyQueryStringInUrl ? '?' : '&') + 'show_me_captcha_please=1';
            }
        } catch (error) {}

        // отправляем запрос и возвращаем результат
        return $.ajax({
            type: 'POST',
            url: '/stat/' + url + query,
            headers: {
                'X-Retpath-Y': BEM.blocks['i-global'].param('retpath'),
                'X-Requested-With': 'XMLHttpRequest'
            },
            dataType: 'json',
            data: params
        });
    };

     // @private
     // @param {number} status
     // @return {bemjson}
    function getErrorPopupContent(status) {
        var errorText = BEM.I18N('i-content-loader', 'Internal server error.');
        var buttonText = BEM.I18N('i-content-loader', 'Try again');
        var buttonMix = [{block: 'b-popupa', elem: 'retry-button'}];

        if (status === 413) {
            errorText = BEM.I18N('i-content-loader', 'Request entity too large.');
            buttonText = BEM.I18N('i-content-loader', 'OK');
            buttonMix = [{block: 'b-popupa', elem: 'close-button'}];
        }

        return [
            {
                block: 'b-popupa',
                elem: 'message',
                tag: 'h3',
                content: [
                    {block: 'b-icon', mods: {'size-16': 'error'}},
                    errorText
                ]
            },
            {
                block: 'b-form-button',
                mods: {type: 'simple', theme: 'simple-grey', size: 'm'},
                mix: buttonMix,
                content: buttonText
            }
        ];
    }

    // @param {object} data
    // @param {jQuery} $container объект jQuery, в который отрисуется загруженный контент
    // @param {string} selector
    function render(data, $container, selector) {
        var key = navigator.userAgent.substr(0, 25) + ($.cookie('fuid01') || '') + eval(data.key);
        var edata = '';
        for (var i=0; i< data.data.length; i++) {
            edata = edata + String.fromCharCode(data.data.charCodeAt(i) ^ key.charCodeAt(i % key.length));
        }

        var bemJson = {content: ''};
        if (edata.match('^%7B.*%7D$')) {
            try {
                edata = decodeURIComponent(edata);
                bemJson = $.parseJSON(edata);
            } catch (e) {}
        }

        var $el = $(BEMHTML.apply(bemJson)),
            $content;

        if (selector) {
            $content = $el.find(selector).html();
        }
        if (selector === undefined || !$content || $content.length === 0) {
            $content = $el;
        }

        BEM.DOM.update($container, $content);
    }

    // ----------------------------

    // i-content-loader

    BEM.decl('i-content-loader', {
        onSetMod: {
            js: function () {
                this._initBlock();
                this._addListeners();
            }
        },

        // Отправляет ajax запрос
        //
        // @public
        // @param {string} url
        // @param {object} params
        // @param {jQuery} renderParams.$container
        // @param {string} renderParams.selector
        // @return {object} Возвращает promise от ajax
        load: function (url, params, renderParams) {
            if (url !== undefined) {
                this._url = url;
                this._params = params;
            } else {
                // если мы повторно посылаем предыдущий запрос
                url = this._url;
                params = this._params;
            }

            if (url !== undefined && url !== null) {
                var promise = load(url, params);

                // если запрос ушел
                if (promise !== undefined && promise !== null) {
                    this._loadPopup.show('slow');

                    promise.success(this._onLoad.bind(this, renderParams))
                        .error(this._showError.bind(this))
                        .always(this._hideLoad.bind(this));
                }

                return promise;
            }
        },

        // @private
        // @param {object} response
        _showError: function (response) {
            var content = BEMHTML.apply(getErrorPopupContent(response.status));
            this._errorPopup.setContent(content);
            this._errorPopup.show();
        },

        // @private
        _hideLoad: function () {
            this._loadPopup.hide('slow');
        },

        // @private
        _initBlock: function () {
            // {b-popup}
            this._loadPopup = $('.b-page__load-popup').bem('b-popupa');
            // {b-popup}
            this._errorPopup = $('.b-page__error-popup').bem('b-popupa');
            // {jQuery}
            this._$content = $('.b-wordstat-content__content');
            // {string}
            this._url = null;
            // {object}
            this._params = null;
            // {string}
            this._captchaKey = null;
        },

        // @private
        _addListeners: function () {
            // @private
            function _onPopupRetryClick() {
                this._errorPopup.hide();
                this.load();
            }

            // @private
            function _onPopupCloseClick() {
                this._errorPopup.hide();
            }

            this._errorPopup.domElem.on('click', '.b-popupa__retry-button', _onPopupRetryClick.bind(this));
            this._errorPopup.domElem.on('click', '.b-popupa__close-button', _onPopupCloseClick.bind(this));
        },

        // @private
        // @param {jQuery} renderParams.$container
        // @param {string} renderParams.selector
        // @param {object} data
        _onLoad: function (renderParams, data) {
            if ('need_login' in data) {
                Lego.block['b-domik_type_popup'].login();
            } else if ('type' in data && 'captcha' == data.type) {
                document.location.href = data.captcha['captcha-page'];
            } else if ('blocked' in data) {
                document.location.href = 'https://wordstat.yandex.ru/block';
            } else if ('data' in data) {
                this.trigger('load', {words: this._params.words, type: this._url});
                if (renderParams === undefined) {
                    renderParams = {};
                }
                render(data, renderParams.$container || this._$content, renderParams.selector);
                this.trigger('render');
            } else {
                this._showError();
            }
        },

    }, {
        getInstance: function () {
            if (iContentLoader === null) {
                iContentLoader = BEM.create('i-content-loader');
            }
            return iContentLoader;
        }
    });
})();
