require(["jquery"], function ($) {
    var boxes = $(".js-calendar-container");
    var sortSelect = $("#calendar-sort");
    var directionButton = $(".js-calendar-sort-direction");
    loadSortAndUpdateSelect();
    sortSelect.on("change", resortLists);
    directionButton.on("click", changeButtonValue);

    $(document).ready(function(){
        resortLists();
    });

    function changeButtonValue() {
        directionButton.val() === "desc" ?  directionButton.val("asc") : directionButton.val("desc");
        resortLists();
    }

    function resortLists() {
        var selected = sortSelect.children("option:selected").val();
        directionButton.tooltip('hide');

        if(directionButton.val() === "desc") {
            directionButton.attr("data-original-title", lmsg('common.descending'));
            directionButton.children("ion-icon").removeAttr('name').attr('name', 'arrow-up-outline');
        } else {
            directionButton.attr("data-original-title", lmsg('common.ascending'));
            directionButton.children("ion-icon").removeAttr('name').attr('name', 'arrow-down-outline');
        }

        directionButton.tooltip({'container': '#filter_form'});

        var direction = directionButton.val();

        boxes.each(function (index, box) {
            box = $(box);
            var children = box.children("[data-calendar-id]");

            children.sort(function (a, b) {
                return sortElements(a, b, selected) * ((direction === "desc") ? -1 : 1);
            });

            box.append(children);
        });

        saveSort(selected, direction);
    }

    function saveSort(field, direction) {
        var sort = field;
        if (direction !== "asc")
            sort = "-" + field;

        setCookie("calendar-sort", sort, 30);
    }

    function loadSort() {
        var sort = getCookie("calendar-sort");
        var direction = "asc";

        if (sort === null)
            return ['id', 'asc'];

        if (sort[0] === '-') {
            direction = 'desc';
            sort = sort.substring(1);
        }

        return [sort, direction];
    }

    function loadSortAndUpdateSelect() {
        var sort = loadSort();

        sortSelect.val(sort[0]);
        directionButton.val(sort[1]);
    }

    function sortElements(a, b, sortBy) {
        var aVal;
        var bVal;
        if (sortBy === "name") {
            aVal = a.dataset.calendarName;
            bVal = b.dataset.calendarName;
        } else {
            var aId = a.dataset.calendarId;
            var bId = b.dataset.calendarId;
            var regex = /-?\d+/;
            aVal = aId.match(regex)?parseInt(aId):aId;
            bVal = bId.match(regex)?parseInt(bId):bId;
        }

        // these short-circuit cases are to ensure that negative IDs are sorted last in ascending and first in descending
        // this ensures that "I'm invited" appears in the place it is expected to
        if (!isNaN(bVal) && bVal < 0)
            return -1;

        if (!isNaN(aVal) && aVal < 0)
            return 1;

        if (aVal < bVal)
            return -1;
        else if (aVal > bVal)
            return 1;
        else
            return 0;
    }
});
