// shortcut suggest functionality
// auto attaches to all [with-shortcuts] elements
(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 && lastTerm !== term) {
            $.get('/pro-suggest?term=' + $.trim(term), 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');
                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]').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 form-control-sm').insertAfter(elem);
            $('<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')) {
                $.get('/pro-display-name/' + elem.attr('data-pro-uid'), function(_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);
                // });

        });

        $(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);
})();


