var CsLinks = function () {

    var CsLinks = function () {

        this.locale = null;

        this.link = this.createLink();

        this.modal = {
            id: 'cs-links-modal',
            html: '',
            options: {},
            searchInput: {},
            resultsContainer: {}
        };

        this.callBack = {};

        this.ajaxCall = true;

        this.externalPrefix = 'http://';
        this.externalPrefixRegex = 'http(s)?://';
    };

    CsLinks.prototype.createLink = function () {
        return {
            href: "",
            target: "_self",
            title: "",
            rel: "follow",
            sponsored: "",
            external: 0,
            intl: {}
        };
    }

    CsLinks.prototype.exec = function (link, callBack) {

        var _this = this;

        this.callBack = callBack;
        this.link = link;

        this.signals.onModalContentLoaded.add(function () {
            _this.bindFunctions();
            _this.setModalOptions();
            $('body').addClass('modal-open-noscroll');
        });

        this.signals.onDestroyModal.add(function () {
            _this.reset();
            $(('#' +_this.modal.id)).remove();
            $('body').removeClass('modal-open-noscroll');
        });

        this.signals.onFetchResults.add(function () {
            _this.modal.searchInput.removeClass('spinner');
            _this.modal.resultsContainer.find('.cs-module-spinner').hide();
        });

        this.signals.onSelectedItem.add(function () {
            _this.ajaxCall = false;
            _this.hideResults();
        });

        this.signals.onInitSearch.add(function () {
            _this.modal.searchInput.trigger('blur');
            _this.modal.searchInput.addClass('spinner');
            _this.modal.resultsContainer.find('.cs-module-spinner').show();
        });

        this.signals.onTapping.add(function () {
            _this.ajaxCall = true;
        });

        this.signals.onFetchLink.add(function (data, item) {
            if (data.link) {
                _this.link.href = data.link;
                _this.modal.html.find('#link-content input').val(data.link);
                _this.toggleContent();
                _this.modal.html.find('#link-submit').prop('disabled', false);

                _this.setLinkTitle(data.title);
            } else {
                _this.hideResults();
            }
        });

        this.signals.onFetchExternalLink.add(function (data, item) {
            if (data.link) {
                var reg = new RegExp(_this.externalPrefixRegex);
                var link = reg.test(data.link) ? data.link : _this.externalPrefix + data.link;

                _this.link.href = link;
                _this.modal.html.find('#link-content input').val(link);
                _this.toggleContent();
                _this.modal.html.find('#link-submit').prop('disabled', false);

                if (item) {
                    _this.setLinkTitle(item.title);
                }
            } else {
                _this.hideResults();
            }
        });

        this.showModal();
    };

    CsLinks.prototype.createModal = function (callBack) {

        var _this = this;

        this.modal.html = $('<div></div>')
            .attr({
                "id": this.modal.id,
                "class": 'modal fade bs-modal-lg',
                "tabindex": "-1",
                "role": "dialog",
                "aria-labelledby": "myModalLabel1",
                "aria-hidden": "true"
            })
            .load(Routing.generate('designer_core_links_modal', {link: _this.link}), function () {
                _this.signals.onModalContentLoaded.dispatch();
            })
            .modal({
                show: false
            });

        $('body').append(this.modal.html);

        this.modal.html.on('hidden.bs.modal', function () {
            _this.destroyModal();
        });

        this.signals.onModalCreated.dispatch();

        callBack.call(this, this);
    };

    CsLinks.prototype.destroyModal = function () {
        this.signals.onDestroyModal.dispatch();
    };

    CsLinks.prototype.showModal = function () {

        this.createModal(function () {
            this.modal.html.modal().show();
        });
    };

    CsLinks.prototype.hideModal = function () {
        this.modal.html.modal('hide');
        this.signals.onHideModal.dispatch();
    };

    CsLinks.prototype.fetchLink = function (item, callBack) {
        var _this = this;
        var data = {
            id: item.entityId,
            type: item.entityType,
            className: item.entityClass,
            locale: _this.locale,
            link: item.publicUrl,
            title: item.title
        };

        _this.signals.onFetchLink.dispatch(data, item);

        if (typeof callBack == 'function') {
            callBack.call(this, data);
        }
    };

    CsLinks.prototype.bindFunctions = function () {

        var _this = this;

        Metronic.init();

        this.modal.searchInput = this.modal.html.find('#link-search-input');
        this.modal.resultsContainer = this.modal.html.find('#link-search-results');

        this.modal.html.on('click', '[data-action="filter-type"] a', function (e) {
            e.preventDefault();

            _this.signals.onTapping.dispatch();

            _this.initSearch({
                q: _this.modal.searchInput.val(),
                type: parseInt($(this).data('type')),
                locale: _this.locale,
                order: $('#search-order', _this.modal.html).val()
            });
        });

        this.modal.html.on('click', '[data-action="fetch-link"]', function (e) {

            e.preventDefault();

            var object = $(this).parents('tr').data('object');

            _this.fetchLink(object);
        });

        this.modal.html.on('click', '#external-link, #internal-link', function (e) {
            e.preventDefault();
            _this.toggleExternalInternal(e.target);
            _this.hideResults();
        });

        this.modal.html.on('click', '#show-advanced-options', function (e) {
            e.preventDefault();
            _this.toggleAdvancedOptions();
        });

        this.modal.html.on('change', '#url-prefix', function (e) {
            e.preventDefault();

            var prefix = $(this).val();

            _this.setExternalPrefix(prefix);

        });

        this.modal.html.on('change', '#url-input', function (e) {
            e.preventDefault();
            var regex = new RegExp('https:\/\/|http:\/\/|mailto:');
            var url = $(this).val();
            var match = regex.exec(url);
            var prefix = $("#url-prefix").val();

            if (match) {
                prefix = match[0];
            }

            _this.setExternalPrefix(prefix);
        });

        this.modal.html.on('click', '#clear-link', function (e) {
            e.preventDefault();
            _this.link.href = '';
            _this.link.external = 0;
            _this.modal.html.find('#link-content input').val(_this.link.href);
            _this.toggleContent();
            _this.hideResults();
        });

        this.modal.html.on('click', '[name="targetRadios"]', function () {
            _this.setLinkTarget($(this).val());
        });

        this.modal.html.on('change', '[name="linkTitle"]', function () {
            _this.setLinkTitle($(this).val());
        });

        this.modal.html.on('click', '[name="followRadios"]', function () {
            _this.setLinkRel($(this).val());
        });

        this.modal.html.on('click', '[name="sponsoredCheck"]', function () {
            var value = $(this).is(':checked') ? $(this).val() : '';
            _this.setLinkRelSponsored(value);
        });

        this.modal.html.on('click', '#link-submit', function () {
            _this.sendCallBack();
        });

        this.modal.html.on('change', '#external-link-content input', function () {

            var value = $(this).val().trim();
            var data = {link: value};

            _this.signals.onFetchExternalLink.dispatch(data);
        });

        this.modal.html.on('change', '#link-content input', function () {
            _this.link.href = $(this).val().trim();
        });

        this.modal.searchInput
            .on('keyup', function (e) {

                var code = e.keyCode || e.which;
                var term = $(e.target).val();

                if (code == 13) {
                    if (term != '') {
                        _this.initSearch({
                            q: term,
                            limit: 5,
                            locale: _this.locale,
                            order: $('#search-order', _this.modal.html).val()
                        });
                    }
                } else {
                    _this.signals.onTapping.dispatch();
                }

                if (term == '') {
                    _this.hideResults();
                }
            })
            .autocomplete({
                source: function (request, response) {
                    _this.suggestResults({
                        q: request.term,
                        limit: 10,
                        locale: _this.locale,
                        order: $('#search-order', _this.modal.html).val()
                    }, function (data) {
                        response(data);
                    });
                },
                minLength: 3,
                focus: function (event, ui) {
                    ui.item.label = ui.item.title;
                    ui.item.value = ui.item.title;
                },
                select: function (event, ui) {
                    _this.signals.onSelectedItem.dispatch();
                    _this.fetchLink(ui.item);
                },
                create: function () {
                    var _$thisAutocomplete = $(this).data("ui-autocomplete");

                    _$thisAutocomplete._renderItem = function (ul, item) {

                        var title = item.title.replace(new RegExp(this.term, "gi"), "<strong>$&</strong>");

                        var html = $('<a></a>', {
                            "href": "javascript: void(0);",
                            "title": item.title,
                            "html": '<span class="info-icon"></span><i class="' + item.icon + '"></i> ' + title
                        });

                        if (!(item.subSite.acronym == $("html").data("subsite"))) {
                            html.append('<span class="subsite">' + item.subSite.name + '</span>');
                        }

                        return $("<li>")
                            .append(html)
                            .appendTo(ul);
                    };

                    _$thisAutocomplete._renderMenu = function (ul, items) {
                        var $this = this;

                        $.each(items, function (index, item) {
                            $this._renderItemData(ul, item);
                        });

                        $(ul).addClass('cs_global_search');
                        $(ul).css('max-width', _this.modal.searchInput.css('width'));
                        $(ul).css('z-index', '99999');
                    };

                    // Remove helper
                    $(this).prev('span').remove();
                }
            });
    };

    CsLinks.prototype.initSearch = function (data, callBack) {

        var _this = this;

        if (_this.ajaxCall === true) {

            $.ajax({
                url: Routing.generate('designer_core_links_search_results'),
                dataType: "html",
                data: data,
                beforeSend: function () {
                    _this.signals.onInitSearch.dispatch();
                },
                success: function (data) {

                    _this.modal.resultsContainer.html(data);

                    _this.showResults();

                    _this.signals.onFetchResults.dispatch();

                    if (typeof callBack == 'function') {
                        callBack.call(this, data);
                    }
                }
            });
        }
    };

    CsLinks.prototype.suggestResults = function (data, callBack) {

        var _this = this;

        $.ajax({
            url: Routing.generate('designer_core_links_suggest_results'),
            dataType: "json",
            data: data,
            beforeSend: function () {
                _this.modal.searchInput.addClass('spinner');
            },
            success: function (data) {

                _this.signals.onFetchResults.dispatch();

                if (typeof callBack == 'function') {
                    callBack.call(this, data);
                }
            }
        });
    };

    CsLinks.prototype.hideAutoComplete = function () {
        this.modal.searchInput.autocomplete("close");
    };

    CsLinks.prototype.showResults = function () {
        this.hideAutoComplete();
        this.modal.resultsContainer.fadeIn();
    };

    CsLinks.prototype.hideResults = function () {
        this.hideAutoComplete();
        this.modal.resultsContainer.fadeOut();
        this.modal.searchInput.removeClass('spinner').val('');
        this.modal.html.find('#link-submit').prop('disabled', true);
        this.modal.html.find('#external-link-content input').val('');
        this.setLinkTitle('', true);
    };

    CsLinks.prototype.toggleContent = function () {
        this.modal.html.find('#link-content input').prop('disabled', this.link.external ? false : true);
        this.modal.html.find('#link-content, #no-link-content').toggle();
    };

    CsLinks.prototype.toggleExternalInternal = function (target) {

        var _this = this;


        //this.modal.html.find('#external-link, #internal-link').parent().toggleClass('active');

        if ($(target).attr('id') == 'internal-link') {

            this.modal.html.find('#external-link-content').fadeOut(1, function () {
                _this.modal.html.find('#internal-link-content').fadeIn(600);
            });

            this.modal.html.find('#optionsRadios1').trigger('click').parent().addClass('checked');
            this.modal.html.find('#optionsRadios3').trigger('click').parent().addClass('checked');
            this.modal.html.find('#optionsRadios2').parent().removeClass('checked');
            this.modal.html.find('#optionsRadios4').parent().removeClass('checked');
            this.link.external = 0;
        } else if ($(target).attr('id') == 'external-link') {

            this.modal.html.find('#internal-link-content').fadeOut(1, function () {
                _this.modal.html.find('#external-link-content').fadeIn(600);
            });


            this.modal.html.find('#optionsRadios2').trigger('click').parent().addClass('checked');
            this.modal.html.find('#optionsRadios4').trigger('click').parent().addClass('checked');
            this.modal.html.find('#optionsRadios1').parent().removeClass('checked');
            this.modal.html.find('#optionsRadios3').parent().removeClass('checked');
            this.link.external = 1;
        }

        this.modal.html.find('#link-content input').prop('disabled', this.link.external ? false : true);
    };

    CsLinks.prototype.toggleAdvancedOptions = function () {
        this.modal.html.find('#advanced-options').slideToggle(400);
        this.modal.html.find('#show-advanced-options').parent().toggleClass('active');
    };

    CsLinks.prototype.reset = function () {
        var _this = this;

        $.each(_this.signals, function (k, v) {
            v.removeAll();
        });

    };

    CsLinks.prototype.sendCallBack = function () {
        if (typeof this.callBack === 'function') {
            this.hideModal();
            this.callBack.call(this, this);
        }
    };

    CsLinks.prototype.setLinkTitle = function (value, force) {

        var val = value || this.link.title;

        if (force) {
            val = '';
        }

        this.modal.html.find('input[name="linkTitle"]').val(val);

        this.link.title = val;
    };


    CsLinks.prototype.setLinkRelSponsored = function (value) {

        var val = value || this.link.sponsored;

        var node = this.modal.html.find('input[name="sponsoredCheck"]');

        if (val === "sponsored" && value !== "") {
            this.link.sponsored = val;
            if (node.is(':checked') === false) {
                node.trigger('click')
            }
        } else {
            this.link.sponsored = "";
        }
    };

    CsLinks.prototype.setLinkRel = function (value) {

        var val = value || this.link.rel;

        if (val) {
            var node = this.modal.html.find('input[name="followRadios"]');

            node.parent().removeClass('checked');

            node.each(function (k, v) {
                if ($(v).val() === val) {
                    $(v).parent().addClass('checked');
                }
            });
        }

        this.link.rel = val;
    };

    CsLinks.prototype.setLinkTarget = function (value) {

        var val = value || this.link.target;

        if (val) {
            var node = this.modal.html.find('input[name="targetRadios"]');

            node.parent().removeClass('checked');

            node.each(function (k, v) {
                if ($(v).val() === val) {
                    $(v).parent().addClass('checked');
                }
            });
        }

        this.link.target = val;
    };

    CsLinks.prototype.setLocale = function (locale) {
        this.locale = locale;
    };

    CsLinks.prototype.setModalOptions = function () {
        this.setLinkTitle();
        this.setLinkRel();
        this.setLinkRelSponsored();
        this.setLinkTarget();
    };

    CsLinks.prototype.signals = {
        onModalCreated: new signals.Signal(),
        onShowModal: new signals.Signal(),
        onHideModal: new signals.Signal(),
        onDestroyModal: new signals.Signal(),
        onFetchResults: new signals.Signal(),
        onModalContentLoaded: new signals.Signal(),
        onTapping: new signals.Signal(),
        onSelectedItem: new signals.Signal(),
        onInitSearch: new signals.Signal(),
        onFetchLink: new signals.Signal(),
        onFetchExternalLink: new signals.Signal()
    };

    CsLinks.prototype.setExternalPrefix = function (prefix) {
        this.externalPrefix = prefix;
        this.modal.html.find('#url-input').attr('placeholder', prefix);
    };

    return {
        init: function () {
            return new CsLinks();
        }
    };
}();
