const autocomplete_query_delay_ms = 60;

class AutocompleteCustomUi {

    static create_media_div(img_src, text_nodes) {
        var ui = document.createElement('div');
        ui.setAttribute('class', 'd-flex align-items-center');
        var img_div = document.createElement('div');
        img_div.setAttribute('class', 'flex-shrink-0');
        var img = document.createElement('img');
        if (img_src != null && img_src != undefined && img_src != '') {
            img.setAttribute('src', img_src);
            img.setAttribute('class', 'component-img-small');
        } else {
            img.setAttribute('src', fallback_img_path);
            img.setAttribute('class', 'component-img-def-small');
        }
                
        img_div.appendChild(img);
        ui.appendChild(img_div);
        var text_div = document.createElement('div');
        text_div.setAttribute('class', 'flex-grow-1 ms-3');
        
        if (text_nodes != undefined) {
            for (var i = 0; i < text_nodes.length; i++) {
                    text_div.appendChild(text_nodes[i]);
            }
        }
        ui.appendChild(text_div)

        return ui
    }

    constructor(text_id, dropdown_id, query_function)
    {
        this.text_id = text_id;
        this.dropdown_id = dropdown_id;
        this.query_callback = query_function.bind(this);
    
        document.getElementById(text_id).addEventListener("keyup", this.ac_delay(function(event) {
            this.query_callback(document.getElementById(this.text_id).value, this);
        }, autocomplete_query_delay_ms).bind(this));

        this.dropdown_data = {};

    }

    /**
     * 
     * @param {*} nodes_to_add A list of dictionaries containing the shown objects and the data called when clicked.
     * 
     * The list: {{'ui': <nodes>, 'data': 'my_data'}, {}, ...}
     * 
     */
    show_results(nodes_to_add, data_clicked_callback) {
        var ul = document.getElementById(this.dropdown_id);
        ul.innerHTML = '';
        this.select_data = {};
        this.dropdown_data = {};

        for (var i = 0; i < nodes_to_add.length; i++) {
            var ui = nodes_to_add[i]['ui'];
            var data = nodes_to_add[i]['data']
            var dropdown_node = document.createElement('li');
            dropdown_node.dataset.ac_clicked = i;
            this.dropdown_data[i] = data;
            dropdown_node.addEventListener('click',
            (e) => {
                data_clicked_callback(this.dropdown_data[e.currentTarget.dataset.ac_clicked]);
                var text_box = document.getElementById(this.text_id);
                var dropdown = bootstrap.Dropdown.getOrCreateInstance(text_box);
                dropdown.hide();
            });
            
            dropdown_node.setAttribute('class', 'dropdown-item');
            dropdown_node.appendChild(ui);
            ul.appendChild(dropdown_node);
        }

        var dropdown = bootstrap.Dropdown.getOrCreateInstance(document.getElementById(this.text_id));
        dropdown.show();
    }

    ac_delay(callback, ms) {
        var timer = 0;
        return function() {
            var context = this, args = arguments;
            clearTimeout(timer);
            timer = setTimeout(function() {
                callback.apply(context, args);
            }, ms || 0);
        };
    }
}

class AutocompleteText extends AutocompleteCustomUi {
    show_results(results) {
        var ul = document.getElementById(this.dropdown_id);
        ul.innerHTML = '';
        for (var i = 0; i < results.length; i++) {
            var node = document.createElement('li');
            node.setAttribute('class', 'dropdown-item');
            node.appendChild(document.createTextNode(results[i]));
            ul.appendChild(node);
            node.addEventListener('click', 
            (e) => {
                var element = e.target;
                var text_box = document.getElementById(this.text_id);
                text_box.value = element.innerHTML;
                var dropdown = bootstrap.Dropdown.getOrCreateInstance(text_box);
                dropdown.hide();
            }
            );
        }
        if (results.length == 0) {
            var node = document.createElement('li');
            node.setAttribute('class', 'dropdown-item text-danger');
            node.appendChild(document.createTextNode('No results'));
            ul.appendChild(node); 
        }

        var dropdown = bootstrap.Dropdown.getOrCreateInstance(document.getElementById(this.text_id));
        dropdown.show();
    }
}