// (C) Copyright 2020 Hewlett-Packard Enterprise Company, L.P.
define(['hp/presenter/SearchBoxPresenter',
        'hp/core/Localizer',
        'hp/services/Log',
        'jquery'], 
function(presenter, localizer, log) {"use strict";

    var SearchBoxView = ( function() {

        var CONTROL = '#hp-search-control';
        var MENU = '#hp-search-menu';
        var HEADER = MENU + ' > header';
        var INPUT = '#hp-search-input input';
        var CLEAR = HEADER + ' #hp-search-clear';
        var SEARCH_SCOPE = '#hp-search-scope';
        var GLOBAL = '#hp-search-scope-global';
        var LOCAL = '#hp-search-scope-local';
        var CHOICES = '#hp-search-choices';
        var SUGGESTIONS = MENU + ' #hp-search-suggestions';
        var SUGGESTION = SUGGESTIONS + ' li';
        var RECENTS = MENU + ' #hp-search-recent';
        var RECENT = RECENTS + ' li';
        var TEMPLATE = MENU + ' #hp-search-item-template';
        var BODY = '#hp-body-div';
        var ACTIVE = "hp-active";
        var SELECTED = "hp-selected";
        var ENTER = 13;
        var ESCAPE = 27;
        var UP_ARROW = 38;
        var DOWN_ARROW = 40;
        // don't stylize MAC addresses as properties, MACs start with two hex digits
        var STYLIZE_REGEXP = /([\w\-\.]{3,256}:)/g;
        
        /**
         * @constructor
         * @type {SearchBoxView}
         */
        function SearchBoxView() {

            var banner;
            var template;
            var preChoice = null;
            
            function stylizeQuery(query) {
                var properties = [];
                // look for [label](url) and put them in links, replace with &&&
                var parsed = query.replace(STYLIZE_REGEXP, function (m, prop) {
                    properties.push($('<span></span>').text(prop).addClass('hp-property'));
                    return '_&&&_';
                });
                $(CONTROL, banner).empty();
                var spans = parsed.split('_&&&_');
                for (var i=0; i<spans.length; i++) {
                    var span = $('<span></span>').text(spans[i]);
                    $(CONTROL, banner).append(span);
                    if (i < properties.length) {
                        $(CONTROL, banner).append(properties[i]);
                    }
                }
            }
            
            function reset() {
                var query = presenter.currentQuery();
                if (query) {
                    stylizeQuery(query);
                    //$(CONTROL, banner).text(query);
                    $(INPUT, banner).val(query);
                } else {
                    $(CONTROL, banner).text(
                        localizer.getString('search.title'));
                    $(INPUT, banner).val('');
                }
            }
            
            function hideRecents() {
                $(RECENTS, banner).hide();
                if ($(SUGGESTION, banner).length === 0) {
                    $(CHOICES, banner).hide();
                }
            }
            
            function showRecents() {
                if ($(RECENT, banner).length > 0) {
                    $(RECENTS, banner).show();
                    $(CHOICES, banner).show();
                }
            }
            
            function clearSuggestions() {
                $(SUGGESTIONS, banner).empty().hide();
                if ($(RECENT, banner).length === 0) {
                    $(CHOICES, banner).hide();
                }
            }
            
            function hideMenu(ev) {
                // don't hide when header is clicked
                if (! ev || $(ev.target).parents(MENU).length === 0) {
                    $(BODY).off('click', hideMenu);
                    $(INPUT, banner).blur();
                    $(MENU, banner).removeClass(ACTIVE);
                    clearSuggestions();
                    presenter.noChoice(true);
                    reset();
                }
            }
            
            function doSearch() {
                var query = $(INPUT).val();
                $(CLEAR, banner).toggle(query.length > 0);
                presenter.doSearch(query);
                clearSuggestions();
                hideRecents();
            }
            
            function chooseChoice(ev) {
                $(INPUT).val($(this).text());
                doSearch();
                hideMenu();
            }
            
            function updateFromChoice() {
                var choice = presenter.currentChoice();
                $(SUGGESTION).removeClass(SELECTED);
                $(RECENT).removeClass(SELECTED);
                if (choice.hasOwnProperty('suggestionIndex')) {
                    if (null === preChoice) {
                        preChoice = $(INPUT).val();
                    }
                    $(INPUT).val(choice.text);
                    $(SUGGESTION + ':eq(' + choice.suggestionIndex + ')').
                        addClass(SELECTED);
                } else if (choice.hasOwnProperty('recentIndex')) {
                    if (null === preChoice) {
                        preChoice = $(INPUT).val();
                    }
                    $(INPUT).val(choice.text);
                    $(RECENT + ':eq(' + choice.recentIndex + ')').
                        addClass(SELECTED);
                } else if (null !== preChoice) {
                    $(INPUT).val(preChoice);
                    preChoice = null;
                }
            }

            function onRecentsChange(recents) {
                var item;
                $(RECENTS, banner).empty();
                if (recents.length > 0) {
                    $.each(recents, function(index, recent) {
                        item = template.clone();
                        item.text(recent);
                        $(RECENTS, banner).append(item);
                    });
                } else {
                    $(RECENTS, banner).hide();
                    if ($(SUGGESTION, banner).length === 0) {
                        $(CHOICES, banner).hide();
                    }
                }
            }
            
            function onSuggestionsChange(data) {
                var item;
                $(SUGGESTIONS, banner).empty();
                if (data.suggestions.length > 0) {
                    $.each(data.suggestions, function(index, suggestion) {
                        item = template.clone();
                        item.text(suggestion);
                        $(SUGGESTIONS, banner).append(item);
                    });
                    $(SUGGESTIONS, banner).show();
                    $(CHOICES, banner).show();
                } else {
                    $(SUGGESTIONS, banner).hide();
                    if ($(RECENT, banner).length === 0) {
                        $(CHOICES, banner).hide();
                    }
                }
            }
            
            function onScopeChange(global) {
                $((global ? GLOBAL : LOCAL), banner).attr('checked', true);
            }
            
            function onKeyDown(ev) {
                if (ENTER === ev.which) {
                    doSearch();
                }
            }
            
            function onKeyUp(e) {
                var keyCode = (e.which ? e.which : e.keyCode);
                if (keyCode == ENTER) {
                    // enter key handled by keydown
                } else if (keyCode == ESCAPE) {
                    hideMenu();
                } else if (keyCode == DOWN_ARROW) {
                    presenter.nextChoice();
                    showRecents();
                    updateFromChoice();
                } else if (keyCode == UP_ARROW) {
                    presenter.previousChoice();
                    showRecents();
                    updateFromChoice();
                } else {
                    presenter.noChoice();
                    preChoice = null; // leave what's there
                    updateFromChoice();
                    var query = $(INPUT).val();
                    $(CLEAR, banner).toggle(query.length > 0);
                    if (query.length > 0) {
                        presenter.getSuggestions(query, 0, 10);
                    } else {
                        clearSuggestions();
                    }
                    showRecents();
                }
            }
            
            function onClear() {
                $(INPUT, banner).val('');
                doSearch();
                $(INPUT, banner).focus();
            }
            
            function showMenu(selectText) {
                $(MENU, banner).addClass(ACTIVE);
                $(INPUT, banner).focus();
                if (selectText) {
                    $(INPUT, banner).select();
                }
                // delay to avoid flickering
                setTimeout(function () {$(BODY).on('click', hideMenu);}, 50);
            }
            
            function onActivate() {
            	// display the x icon if there is any text in the search box 
            	$(CLEAR, banner).toggle($(INPUT, banner).val().length > 0);
                // adjust banner search width on right depending upon the icons
                $(MENU, banner).css('right', $('#hp-main-banner .hp-header-secondary').outerWidth());
                if (! $(MENU, banner).hasClass(ACTIVE)) {
                    showMenu();
                }
            }
            
            function onChangeScope() {
                presenter.setGlobal($(this).val() === 'global', $(INPUT).val());
                $(INPUT, banner).focus();
            }

            /**
             * @public
             */
            this.init = function(bannerArg) {
                banner = bannerArg;
                template = $(TEMPLATE, banner);
                template.removeAttr('id').detach().removeClass('hp-template');
                
                presenter.init();
                presenter.on('suggestionsChange', onSuggestionsChange);
                presenter.on('recentsChange', onRecentsChange);
                presenter.on('scopeChange', onScopeChange);
                
                $(LOCAL, banner).attr('checked', true);
                
                $(SEARCH_SCOPE + ' input', banner).on('click', onChangeScope);
                $(CONTROL, banner).on('click', onActivate);
                $(CLEAR, banner).on('click', onClear);
                $(CHOICES, banner).on('click', 'li', chooseChoice);
                
                $(INPUT, banner).on('keyup', onKeyUp).on('keydown', onKeyDown);
            };
            
            // used by SearchView to focus on resume()
            this.activate = function (selectText) {
                showMenu(selectText);
            };
            
            this.setCategory = function (category, label) {
                if (presenter.setCategory(category)) {
                    // setCategory() returns true if the category changed.
                    // we only want to reset the search if we change pages
                    
                    if (category) {
                        $('label[for="hp-search-scope-local"]', banner).text(label);
                        $(SEARCH_SCOPE, banner).show();
                        presenter.reset(false, '');
                    } else {
                        $(SEARCH_SCOPE, banner).hide();
                        presenter.reset(true, '');
                    }
                    reset();
                }
            };
            
            this.setLocal = function (localLabel) {
                if (localLabel) {
                    $("label[for='hp-search-scope-local']", banner).text(localLabel);
                    $(SEARCH_SCOPE, banner).show();
                    presenter.reset(false, '');
                    reset();
                }
            };
            
            this.setLocalSearchText = function (query) {
                presenter.reset(false, query);
                reset();
            };
            
            this.setGlobalSearchText = function (query) {
                presenter.reset(true, query);
                reset();
            };
        }

        return new SearchBoxView();
    }());

    return SearchBoxView;
});

