// pro suggest functionality
(function() {

    let suggestionsOuter = null;

    const debounce = (func, wait) => {
        let timeout;
        return function executedFunction(...args) {
            const later = () => {
                clearTimeout(timeout);
                func(...args);
            };
            clearTimeout(timeout);
            timeout = setTimeout(later, wait);
        };
    };

    var lastTerm = '';
    var returnedFunction = debounce(function (elem) {
        var term = elem.val();
        if(term === '') {
            let select = suggestionsOuter.closest('.position-relative')
                .prev('.pro-suggest-input')
                .prev('select[provider-search]');
            select.empty().val('').append($('<option value="" selected/>').text('')).trigger('change');
            suggestionsOuter.addClass('d-none');
        }
        else {
            if (!!term && lastTerm !== term) {
                $.get('/pro-suggest?term=' + $.trim(term) + '&type=' + elem.attr('provider-type'), function (_data) {
                    suggestionsOuter.html(_data).removeClass('d-none');
                });
                lastTerm = term;
            } else {
                suggestionsOuter.addClass('d-none');
            }
        }
    }, 250);

    function handleKeydown(elem, e) {
        let term = $.trim(elem.val());
        let activeItem = suggestionsOuter.find('.suggest-item.active');
        switch (e.which) {
            case 27:
                suggestionsOuter.addClass('d-none');
                markEventAsConsumed(e);
                return false;
            case 38:
                if (activeItem.prev().length) {
                    activeItem.prev()
                        .addClass('active')
                        .siblings().removeClass('active');
                    activeItem = suggestionsOuter.find('.suggest-item.active');
                    if (activeItem.length) {
                        activeItem[0].scrollIntoView();
                    }
                }
                return false;
            case 40:
                if (activeItem.next().length) {
                    activeItem.next()
                        .addClass('active')
                        .siblings().removeClass('active');
                    activeItem = suggestionsOuter.find('.suggest-item.active');
                    if (activeItem.length) {
                        activeItem[0].scrollIntoView();
                    }
                }
                return false;
            case 13:
                if (activeItem.length) {
                    activeItem.first().click();
                }
                return false;
            default:
                if (!!term) {
                    suggestionsOuter
                        .html('<span class="d-block no-suggest-items">Searching...</span>')
                        .removeClass('d-none');
                    returnedFunction(elem);
                } else {
                    suggestionsOuter.addClass('d-none');
                }
                break;
        }
    }

    function handleKeypress(elem, e) {
        var term = $.trim(elem.val());
        if (!!term) {
            suggestionsOuter
                .html('<span class="d-block no-suggest-items">Searching...</span>')
                .removeClass('d-none');
            returnedFunction(elem);
        } else {
            suggestionsOuter.addClass('d-none');
        }
    }

    window.initProSuggest = function() {

        // make select[provider-search] hidden & insert a textbox with pro-suggest
        $('select[provider-search]:not([pro-suggest-initialized]):not([no-auto-pro-suggest-init])').each(function() {
            let elem = $(this);
            elem.next('.pro-suggest-input').remove();
            elem.next('.pro-suggestions-container').remove();
            let input = $('<input type="text" placeholder="Pro">').addClass('pro-suggest-input form-control').insertAfter(elem);
            if($(this).is('.form-control-sm')) input.addClass('form-control-sm');
            input.attr('provider-type', elem.attr('provider-type'));
            $('<div class="pro-suggestions-container position-relative">' +
                '<div class="suggestions-outer pro-suggestions position-absolute d-none"></div>' +
                '</div>').insertAfter(input);
            elem.hide();

            if (!!elem.attr('data-pro-uid')) {
                if (!!localStorage["proDisplayNameCache_" + elem.attr('data-pro-uid')]) {
                    let name = localStorage["proDisplayNameCache_" + elem.attr('data-pro-uid')];
                    input.val(name).data('original', name);
                    elem.empty().append($('<option value="' + elem.attr('data-pro-uid') + '" selected/>').text(name));
                }
                else {
                    $.get('/pro-display-name/' + elem.attr('data-pro-uid'), function (_data) {
                        localStorage["proDisplayNameCache_" + elem.attr('data-pro-uid')] = _data;
                        input.val(_data).data('original', _data);
                        elem.empty().append($('<option value="' + elem.attr('data-pro-uid') + '" selected/>').text(_data));
                    });
                }
            }
            else {
                input.val(elem.attr('data-pro-name')).data('original', elem.attr('data-pro-name'));
            }

            if(elem.is('[required]')) {
                input.attr('required', 'required');
            }

            input
                .off('keydown.pro-suggest')
                .on('keydown.pro-suggest', function (e) {
                    suggestionsOuter = $(this).next('.pro-suggestions-container').find('>.suggestions-outer');
                    return handleKeydown($(this), e);
                })
                .off('keypress.pro-suggest')
                .on('keypress.pro-suggest', function (e) {
                    suggestionsOuter = $(this).next('.pro-suggestions-container').find('>.suggestions-outer');
                    return handleKeypress($(this), e);
                });
                // .off('blur.pro-suggest')
                // .on('blur.pro-suggest', function (e) {
                //     window.setTimeout(() => {
                //         $(this).next('.pro-suggestions-container').find('>.suggestions-outer').addClass('d-none');
                //         $(this).val($(this).data('original'));
                //     }, 50);
                // });

            $(this).attr('pro-suggest-initialized', 1);
        });

        $(document).off('click', '.suggest-item.pro-suggest[data-target-uid]');
        $(document).on('click', '.suggest-item.pro-suggest[data-target-uid]', function () {

            $('.suggestions-outer.pro-suggestions').addClass('d-none');

            let uid = $(this).attr('data-target-uid'),
                label = $.trim($(this).text());

            // set select value
            let select = $(this).closest('.position-relative')
                .prev('.pro-suggest-input')
                .prev('select[provider-search]');
            select.empty().append($('<option value="' + uid + '" selected/>').text(label));
            select.val(uid).trigger('change');
            select.trigger('pro-changed');

            // set input value
            $(this).closest('.position-relative')
                .prev('.pro-suggest-input')
                .val(label)
                .data('original', label)
                .trigger('change');

            return false;
        });

    }
    addMCInitializer('pro-suggest', initProSuggest);
})();


