var EntityInputSearch = function (searchInput, orderElement, resultsContainer, locale, options) {
    this.searchInput = searchInput;
    this.orderElement = orderElement;
    this.resultsContainer = resultsContainer;
    this.locale = locale;
    this.handlers = {
        onFetchResults: new signals.Signal(),
        onInitSearch: new signals.Signal(),
        onTapping: new signals.Signal(),
        onSelectedItem: new signals.Signal(),
        onFetchLink: new signals.Signal(),
        onHideResults: new signals.Signal(),
    };
    this.options = {
        types: "",
        existUrl: true
    };

    Object.assign(this.options, options);
};

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

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

EntityInputSearch.prototype.hideResults = function () {
    this.handlers.onHideResults.dispatch();
    this.hideAutoComplete();
    this.resultsContainer.fadeOut();
    this.searchInput.removeClass("spinner");
};

EntityInputSearch.prototype.searchResults = function (data, onSuccess) {
    var _this = this;

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

            _this.showResults();

            _this.handlers.onFetchResults.dispatch();

            if (typeof onSuccess === "function") {
                onSuccess.call(this, data);
            }
        }
    });
};

EntityInputSearch.prototype.suggestResults = function (data, callBack) {
    var _this = this;

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

            _this.searchInput.removeClass("spinner");

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

EntityInputSearch.prototype.bindSearch = function () {
    var _this = this;

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

        _this.handlers.onTapping.dispatch();

        _this.searchResults({
            q: _this.searchInput.val(),
            type: parseInt($(this).data("type")),
            locale: _this.locale,
            order: _this.orderElement.val(),
            existUrl: _this.options.existUrl
        });
    });

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

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

            if (code === 13) {
                if (term !== "") {
                    _this.searchResults({
                        q: term,
                        limit: 5,
                        locale: _this.locale,
                        order: _this.orderElement.val(),
                        type: _this.options.types,
                        existUrl: _this.options.existUrl
                    });
                }
            } else {
                _this.handlers.onTapping.dispatch();
            }

            if (term === "") {
                _this.hideResults();
            }
        })
        .autocomplete({
            source: function (request, response) {
                _this.suggestResults({
                    q: request.term,
                    limit: 10,
                    locale: _this.locale,
                    order: _this.orderElement.val(),
                    type: _this.options.types,
                    existUrl: _this.options.existUrl
                }, 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.handlers.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.searchInput.css('width'));
                    $(ul).css('z-index', '99999');
                };

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

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

    $.ajax({
        url: Routing.generate("cs_core_links_generate"),
        dataType: "json",
        data: data,
        success: function (data) {

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

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