$(document).ready(function () {
    select2();
    select2multiple();
    select2withAPI();
    select2OnClick();
});

function select2multiple() {
    $(".select2multiple").select2({
        minimumInputLength: 0,
        theme: "bootstrap",
        multiple: true
    });
}

//Select2 dropdown with URL
function select2withAPI() {
    $(".select2withAPI").each(function (index, element) {
        let multiple = $(element).attr('multiple');
        let allowClear = false;
        let tags = false;

        if ($(element).attr('allow-clear') !== undefined) {
            allowClear = true;
        }

        if ($(element).attr('tags') !== undefined) {
            tags = true;
        }

        if (multiple) {
            initializeSelect2WithAPI(element, allowClear, tags, false);
        }
        else {
            initializeSelect2WithAPI(element, allowClear, tags, true);
        }
    });
}

function select2OnClick() {
    $(".select2OnClick").on("mouseover", function (index, element) {
        let allowClear = false;
        let tags = false;

        if ($(element).attr('allow-clear') !== undefined) {
            allowClear = true;
        }

        if ($(element).attr('tags') !== undefined) {
            tags = true;
        }

        $("#" + this.id).next("span").remove();
        initializeSelect2WithAPI($("#" + this.id), allowClear, tags, true);
    });
}

function select2APIdebouncer(func, wait) {
    let timeout;
    let ajaxr;
    return function() {
        const context = this;
        const args = arguments;
        const later = function() {
            timeout = null;
            if(ajaxr){
                ajaxr.abort();
            }
            ajaxr = func.apply(context, args);
        };
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
    };
}


var select2debouncedSearch = select2APIdebouncer(function(settings, callback) {
    return $.ajax({
        url: settings.url,
        dataType: settings.dataType,
        type: settings.type,
        data: settings.data,
        success: function (data) {
            callback(data);
        }
    });
}, 400);

var select2WithAPIResponseFilters = {};

function initializeSelect2WithAPI(element, allowClear = true, allowTags = false, customizeInput = false) {
    let columns;
    let columnSizes;
    let placeholder = $(element).attr('data-placeholder');
    if (!placeholder) {
        placeholder = '';
    }

    $(element).on("select2:unselecting", function (e) {
        $(this).select2("val", "");
        e.preventDefault();
    });

    $(element).on('select2:open', function (e) {
        $('.rowHeader').remove();

        let html = '<div class="rowHeader"><div class="row" style="margin-left:0px !important; margin-right:17px;">';
        let searchWidth = $(element).attr('data-search-width');
        let inputWidth = $(element).attr('data-input-width');
        let headerDef = '<div class="select2HeaderCustom ColumnSize">HeaderContent</div>';
        var cols = $(element).attr("data-column-names");
        var colSizes = $(element).attr("data-bootstrap-columns");
        var searchLeft = $(element).attr("data-search-left");
        let mobileWidth = $(element).attr("data-mobile-width");
        let dropdownHeight = $(element).attr("data-dropdown-height");

        if (searchWidth) {
            if (isTablet()) {
                searchWidth = 350;
            }
            else if (isMobile()) {
                searchWidth = window.innerWidth - 50;
            }

            $('.select2-dropdown').addClass('select2-dropdown-large');
            $('.select2-dropdown').css({
                "min-width": searchWidth + "px"
            });
        }

        if (mobileWidth) {
            if (isMobile() && mobileWidth > (window.innerWidth - 50)) {
                mobileWidth = window.innerWidth - 50;
            }

            $('.select2-dropdown').css({
                "min-width": mobileWidth + "px"
            });
        }

        if (searchWidth && mobileWidth) {
            if (window.innerWidth > 768) {
                $('.select2-dropdown').css({
                    "min-width": searchWidth + "px"
                });
            } else {
                $('.select2-dropdown').css({
                    "min-width": mobileWidth + "px"
                });
            }
        }

        if (inputWidth) {
            $('.select2-container').css({
                "max-width": inputWidth + "px"
            });
        }

        if (dropdownHeight) {
            $('.select2-results__options').css({
                "height": dropdownHeight + "px"
            });
        }

        if (cols) {
            columns = cols.split(',');
        } 

        if (colSizes) {

            if (isTablet()) {
                colSizes = colSizes.replaceAll("md", "sm");
            }
            else if (isMobile()) {
                colSizes = colSizes.replaceAll("md", "xs");
            }

            columnSizes = colSizes.split(',');        
        }

        if (searchLeft) {
            if (!isTablet() && !isMobile()) {
                $('.select2-dropdown').css({ "left": searchLeft + "px" });
            }
        }

        if (columns) {
            for (i = 0; i < columns.length; i++) {
                html += headerDef.replace('HeaderContent', columns[i]).replace('ColumnSize', columnSizes[i]);
            }
        }

        html += "</div></div>";

        if (html !== '') {
            $('.select2-results').prepend(html);
        }

        if (paw.utils.value.strToBool($(element).data('right-align'))) {
            forceRightAlign($(element))
        }
    });

    var attachTo = $(element).data('attach-to');
    var closeOnSelect = $(element).data('close-onselect');
    let options = {
        maximumSelectionSize: 1,
        placeholder: placeholder,
        allowClear: allowClear,
        minimumInputLength: 0,
        tags: allowTags,
        theme: "bootstrap",
        dropdownParent: attachTo ? $(attachTo) : undefined,
        closeOnSelect: paw.utils.value.isSet(closeOnSelect) ? paw.utils.value.strToBool(closeOnSelect) : undefined,
        ajax: {
            url: function () {
                return $(this).attr('data-url');
            },
            dataType: 'json',
            type: "GET",
            data: function (params) {
                var filterBy = $(this).attr('filter-by');
                var filterWorker = $(this).attr('filter-by-worker');
                var filterCountry = $(this).attr('filter-by-country');
                var filterSubject = $(this).attr('filter-by-subject');

                if (filterBy !== null) {
                    var filter = $("#" + filterBy).val();
                }
                if (filterWorker !== null) {
                    var worker = $("#" + filterWorker).val();
                }
                if (filterCountry !== null) {
                    var country = $("#" + filterCountry).val();
                }
                if (filterSubject !== null) {
                    var subject = $("#" + filterSubject).val();
                }
                return {
                    searchTerm: params.term,
                    worker: worker,
                    country: country,
                    subjectId: subject,
                    filterBy: filter
                };
            },

            processResults: function (data) {
                if ($(element).attr('data-select2-api-response-filter')) {
                    var filterId = $(element).attr('data-select2-api-response-filter');
                    var filter = select2WithAPIResponseFilters[filterId];
                    if (paw.utils.value.isFunction(filter)) {
                        data = filter(data);
                    }
                }
                return {
                    results: $.map(data, function (item, index) {
                        return {
                            id: item[Object.keys(item)[0]],
                            text: item[Object.keys(item)[1]],
                            index: index,
                            columnSizes: columnSizes,
                            columns: columns,
                            element: element
                        };
                    })
                };
            },
            transport: function (params, success, failure) {
                select2debouncedSearch(
                    {
                        url: params.url,
                        dataType: params.dataType,
                        type: params.type,
                        data: params.data
                    },
                    success);
            }

        },
        templateResult: formatResult,
        templateSelection: formatSelection,
        escapeMarkup: function (m) { return m; }
    };

    if (!$(element).data('select2')) {
        $(element).select2(options);

        select2Focus(element);

        select2Selected(element);

        paw.helper.select2MultiselectHelper.init($(element));
    }
}

function formatSelection(data) {
    let text = '';
    let splittedData = data.text.split('|');
    let separator = '';
    var element = data.element;
    var selectorSeparator = $(element).parent().attr("data-selector-separator");
    var firstColumnOnly = $(element).parent().attr("data-first-column-only");
    
    if (firstColumnOnly === "true") {
        text = splittedData[0];
        return text;
    }

    for (i = 0; i < splittedData.length; i++) {

        if (i > 0) {
            if (selectorSeparator) {
                separator = selectorSeparator;
            } else {
                separator = ', ';
            }
        }

        let trimmedData = splittedData[i].trim();
        let formattedText = trimmedData.length > 0 ? separator + trimmedData : '';
        text += formattedText;
    }

    return text;
}

function formatResult(data) {
    var $elt = $(data.element);
    let html = '<div class="row ' + paw.helper.select2MultiselectHelper.multivalueSelectedClass($elt, data.id) + '" style="margin-left:0px !important; margin-right:0px !important; position: relative;" data-select2-id="' + data.id + '">';
    let rowDefinition = '<div class="select-option-custom ColumnSize">';

    let isColumnGathering = $elt.length > 0 ? true : false;
    let columnGathering = $elt.attr("data-column-gathering");
    let isMobileOrTablet = isMobile() || isTablet();
    
    if (data.columns && data.columns.length > 0) {
        let dataArray = data.text.split('|');
        let columnGatheringText = "";

        if (isColumnGathering && isMobileOrTablet) {
            rowDefinition = '<div class="select-option-custom option-column-gathering  ColumnSize">';

            for (i = 0; i < columnGathering; i++) {
                if (columnGathering === 1 || i === columnGathering - 1 || dataArray[columnGathering - i].trim() === "") {
                    columnGatheringText += dataArray[i + 1]; 
                } else {
                    columnGatheringText += dataArray[i + 1] + " • ";
                }
            };
        }

        for (i = 0; i < data.columns.length; i++) {
            if (isColumnGathering && isMobileOrTablet && i === 0 ) {
                html += rowDefinition.replace('ColumnSize', data.columnSizes[i]) + dataArray[i] + '<p class="gathering-text">' + columnGatheringText + '</p>'+ '</div>';
            } else if (i <= columnGathering && isMobileOrTablet) {
                html += rowDefinition.replace('ColumnSize', data.columnSizes[i]) + '</div>';
            } else {
                html += rowDefinition.replace('ColumnSize', data.columnSizes[i]) + dataArray[i] + '</div>';
            }
        }
    }
    else {
        html += rowDefinition.replace('ColumnSize', 'col-md-12') + data.text + '</div>';
    }

    html += paw.helper.select2MultiselectHelper.markupSelectionChecked($elt, data.id);

    html += '</div>';
    return $(html);
}

function select2Configuration(element) {
    let allowClear = false;

    if ($(element).attr('allow-clear') !== undefined) {
        allowClear = true;
    }

    let placeholder = $(element).attr('data-placeholder');

    if (!placeholder) {
        placeholder = $(element).attr('placeholder');
    }

    if (!placeholder) {
        placeholder = '';
    }

    $(element).on('select2:open', function (e) {
        $('.rowHeader').remove();

        let searchWidth = $(element).attr('data-search-width');
        if (searchWidth) {
            $('.select2-dropdown').css({
                "min-width": searchWidth + "px"
            });
        }
    });

    $(element).select2({
        allowClear: allowClear,
        placeholder: placeholder,
        minimumInputLength: 0,
        theme: "bootstrap",
        templateResult: formatResult
        //selectionAdapter: $.fn.select2.amd.require("SearchableSingleSelection"),
        //dropdownAdapter: $.fn.select2.amd.require("UnsearchableDropdown")
    });
}

function select2() {
    $(".select2").each(function (index, element) {
        select2Configuration(element);
    });
}

function initializeSelect2ByElement(element) {
    select2Configuration(element);
}

function select2Focus(element) {
    var focus = $(element).attr('data-focus');
    if (focus) {
        $(element).select2('focus');
    }
}

function select2Selected(element) {
    $(element).on('select2:select', function (e) {
        var allowSubmit = $(element).attr("data-submit");
        if (allowSubmit) {
            $("#" + allowSubmit).focus();
        }

        paw.helper.select2MultiselectHelper.onItemSelected($(element), e.params.data.id);
    });
}

function isTablet() {
    let tabletWidth = 768;
    let mobileWidth = 576;

    if (window.innerWidth <= tabletWidth && window.innerWidth >= mobileWidth)
        return true;

    return false;
}

function isMobile() {
    let mobileWidth = 576;

    if (window.innerWidth < mobileWidth)
        return true;

    return false;
}

function forceRightAlign($elt) {
    var select2 = $elt.data('select2');
    var $dropdown = select2.$dropdown;
    var $select = select2.$element;

    
    var selectOffset = $select.offset();
    let calculatedLeft = selectOffset.left;

    var windowWidth = $(window).width();

    var isAlignedRight = $dropdown.hasClass('paw-select2-right-align');
    if (calculatedLeft + $dropdown.outerWidth() > windowWidth) {
        // Align to the right if it exceeds the window width
        if (!isAlignedRight) {
            $dropdown.addClass('paw-select2-right-align');
        }
    }
    else if (isAlignedRight) {
        $dropdown.removeClass('paw-select2-right-align');
    }
}