var filters = {"ordering": "-edit_timestamp"};
    global_loadingTickets = false;
    searchTimeout = null;
    pagination = {};
    complexItems = false;

$(document).ready(function() {
    initSearchBar();

    setupFilter("#filterSidebar .filter-department", "author__department");
    setupFilter("#filterSidebar .filter-tags", "tags");
    setupFilter("#filterSidebar .filter-priority", "priority");

    loadFilterCounts();
    loadTicketItems();
});

function updateItemsState(state) {
    console.debug(`updating items state to '${state}'`);
    switch (state) {
        case "content":
            $("#ticketsContainer .none-found").hide();
            $("#ticketsContainer .loading").hide();
            break;
        case "loading":
            $("#ticketsContainer .content").empty();
            $("#ticketsContainer .none-found").hide();
            $("#ticketsContainer .loading").show();
            break;
        case "no-content":
            $("#ticketsContainer .content").empty();
            $("#ticketsContainer .none-found").show();
            $("#ticketsContainer .loading").hide();
            break;
        default:
            throw new Error(`Invalid Items State '${state}'`);
    }
}

function updateContentState(state) {
    console.debug(`updating content state to '${state}'`);
    switch (state) {
        case "content":
            $("#ticketContent .loading").hide();
            break;
        case "loading":
            $("#ticketContent .content").empty();
            $("#ticketContent .loading").show();
            break;
        default:
            throw new Error(`Invalid Content State '${state}'`);
    }
}

function initSearchBar() {
    $("#searchTickets").keyup(() => {
        updateItemsState("loading");
        clearTimeout(searchTimeout);
        searchTimeout = setTimeout(() => {
            console.debug("searching");
            value = $("#searchTickets").val();
            if (value === "") {
                console.debug("deleted search filters");
                delete filters["search"];
            }
            else {
                console.debug("updated search filters");
                filters["search"] = value;
            }

            loadTicketItems();
        }, 500);
    })
}

function setupFilter(selector, key) {
    $(selector).each(function () {
        var input = $(this).find("input[type=checkbox], input[type=radio]");
        var uuid = input.val();

        input.on("change", function () {
            if (input.is(":checkbox")) {
                if ($(this).is(":checked")) {
                    filters[key] = filters[key] || [];
                    filters[key].push(uuid);
                }
                else {
                    filters[key] = filters[key].filter(id => id !== uuid);
                    if (filters[key].length === 0) delete filters[key];
                }
            }
            else if (input.is(":radio") && input.is(":checked")) {
                if (uuid === "all") delete filters[key];
                else filters[key] = [uuid];

                const deselectOption = $(`[name='${input.prop("name")}'].deselect-radio-filters`);

                if (deselectOption.length) {
                    if (deselectOption.prop("checked")) deselectOption.parent().hide();
                    else deselectOption.parent().show();
                }
            }

            console.debug(`Filter applied '${key}' as '${uuid}'`)
            loadTicketItems();
        });
    });
}

function getOrdinalSuffix(day) {
    if (day >= 11 && day <= 13) {
        return day + 'th';
    } else {
        switch (day % 10) {
            case 1: return day + 'st';
            case 2: return day + 'nd';
            case 3: return day + 'rd';
            default: return day + 'th';
        }
    }
}

function timestampToHumanDate(timestamp, wasYesterday) {
    if (wasYesterday) {
        var day = getOrdinalSuffix(timestamp.getDate());
        var month = timestamp.toLocaleString('en-GB', { month: 'short' });
        var year = timestamp.toLocaleString('en-GB', { year: 'numeric' });
        var time = timestamp.toLocaleString('en-GB', { hour: 'numeric', minute: 'numeric' });
        return time + ', ' + day + ' ' + month + ' ' + year;
    }

    var hours = timestamp.getUTCHours();
    var minutes = timestamp.getUTCMinutes();
    return hours.toString().padStart(2, '0') + ':' + minutes.toString().padStart(2, '0');
}

function updateFilterCounts(filterType, data) {
    $("#filterSidebar .filter-" + filterType).each(function() {
        var uuid = $(this).find("input[type=checkbox],input[type=radio]").val();
        var count = data[filterType][uuid];
        $(this).find(".badge").text(count);
    });
}

function loadFilterCounts() {
    $.ajax({
        url: URL_FilterCounts,
        type: "GET",
        success: function(data) {
            updateFilterCounts('priority', data);
            updateFilterCounts('tags', data);
            updateFilterCounts('department', data);

            // $("#filterPriorityAll .badge").text(data.tickets);
            // $("#filterDepartmentAll .badge").text(data.tickets);
            // $("#ticketCounts .total").text(data.tickets);
        },
        error: function(data) {
            console.error(JSON.stringify(data, null, 4))
        }
    });
}

function applyTicketClickFunction() {
    $(".ticket-item").on("click", function(e) {
        e.preventDefault();
        if ($(this).hasClass("active")) {
            return;
        }

        loadTicketContent($(this).data("uuid"));
        $(".ticket-item").removeClass("active");
        $(this).addClass("active");
        $('.email-app').removeClass('side-active');
        $('.email-content').toggleClass('open');
    });
}

$(".back-to-mailbox").on("click", function(e) {
    e.preventDefault();
    $(".ticket-item.active").removeClass("active");
});

function reloadCurrentTicket() {
    loadTicketContent($(".ticket-item.active").data("uuid"));
}

function changeTicket(next=true) {
    var selectedTicket = $(".ticket-item.active");
    var uuid;

    if (!selectedTicket.length) selectedTicket = $(".ticket-item").first();
    else if (next) selectedTicket = selectedTicket.next();
    else selectedTicket = selectedTicket.prev();

    $(".ticket-item").removeClass("active");
    selectedTicket.addClass("active");
    uuid = selectedTicket.data("uuid");
    loadTicketContent(uuid);

    if (!$('.email-content').hasClass('open')) {
        $('.email-content').addClass('open');
    }
}

function changeItemsPage(next) {
    $("#ticketItemsNextPage").prop("disabled", true);
    $("#ticketItemsPrevPage").prop("disabled", true);

    var page = pagination.page;

    if (next && pagination.next) page ++;
    else if (!next && pagination.prev) page --;
    else return;

    loadTicketItems(page);
}

function loadTicketItems(page=1) {
    updateItemsState("loading");
    filters["page"] = page;

    var fetchFilters = { ...filters };
    fetchFilters["only_fields"] = "uuid,title,short_description,author,priority,tags,timestamp,is_edited,author__forename,author__surname,author__department,author__icon,string_datetime";

    fetchTicketsPromise(fetchFilters).then((response) => {
        // Update the counts to show how many tickets were found
        $("#ticketCounts .current").text(response.results.length);
        $("#ticketCounts .total").text(response.count);
    
        // If there are no tickets
        if (!response.count) {
            updateItemsState("no-content");
            return;
        }

        const ticketHasNextPage = typeof response.next === "string";
        const ticketHasPrevPage = typeof response.previous === "string";
        $("#ticketItemsNextPage").prop("disabled", !ticketHasNextPage);
        $("#ticketItemsPrevPage").prop("disabled", !ticketHasPrevPage);
        const pageNumber = filters["page"] || 1;  // If we haven't tracked the page, it's safe to assume it's 1,
        pagination = {                            // because we always track it when it changes.
            "page": pageNumber,
            "next": ticketHasNextPage,
            "prev": ticketHasPrevPage
        }

        // Update the pagination count with the current page
        $("#paginationCounts .current").text(pageNumber);

        // If we are on page one (which has been normalised to be the case in many intances)
        // We can use the amount of results to calculate the total amount of pages.
        if (pageNumber === 1) {
            $("#paginationCounts .total").text(Math.ceil(response.count / response.results.length));
        }

        // Iterate over and handle each ticket
        response.results.forEach(function(ticket) {
    
            // Create a copy of the template using the ticket data
            var template = $($("#ticketItemTemplate").html());
            template.find(".ticket-item-author").text(`${ticket.author.forename} ${ticket.author.surname}`);
            template.find(".ticket-item-datetime").text(ticket.string_datetime);
            template.find(".ticket-item-title").text(ticket.title);
            template.find(".ticket-item-desc").html(ticket.short_description);
            template.find(".ticket-item-icon").attr("src", ticket.author.icon);
            template.attr("data-uuid", ticket.uuid);

            // Add tickets using the badge template
            ticket.tags.forEach(function(tag) {
                var tagTemplate = $($("#ticketContentBadgeTemplate").html());
                tagTemplate.find(".ticket-content-badge-text").text(tag.title);
                tagTemplate.css({ "color": tag.colour, "background-color": tag.backgroundcolour });
                template.find(".ticket-item-tags").append(tagTemplate);
            });

            var priorityElem = template.find(".ticket-item-priority");
            // priorityElem.text(ticket.priority.title);
            priorityElem.css("color", ticket.priority.colour);
            priorityElem.css("background-color", ticket.priority.backgroundcolour);

            var departmentElem = template.find(".ticket-item-department");
            departmentElem.addClass("bgc-orange-100 c-orange-700")

            // // Add the priority using the badge template
            // var priorityTemplate = $($("#ticketContentBadgeTemplate").html());
            // priorityTemplate.find(".ticket-content-badge-text").text(ticket.priority.title + " Priority");
            // priorityTemplate.css({ "color": ticket.priority.colour, "background-color": ticket.priority.backgroundcolour });
            // priorityTemplate.removeClass("rounded-pill").addClass("rounded-1");
            // template.find(".ticket-item-priority").append(priorityTemplate);
    
            // Add the content to the interface
            $("#ticketsContainer .content").append(template);
        });
    
        // Make tickets clickable
        applyTicketClickFunction();
    
        updateItemsState("content");
    });
}

function loadTicketContent(uuid) {
    updateContentState("loading");

    if (global_loadingTickets) {
        console.debug("Spam prevention\nStopped loadTicketContent because already loading.");
        return;
    }

    $("#ticketContent .content").empty();

    fetchTicketsPromise({uuid: uuid}).then((response) => {
        ticket = response.results[0];

        // Create a copy of the template using the ticket data
        var template = $($("#ticketContentTemplate").html());
        template.find(".ticket-content-author").text(`${ticket.author.forename} ${ticket.author.surname}`);
        template.find(".ticket-content-datetime").text(ticket.string_datetime);
        template.find(".ticket-content-title").text(ticket.title);
        template.find(".ticket-content-desc").html(ticket.description);
        template.find(".ticket-content-icon").attr("src", ticket.author.icon);
        console.debug(ticket.description);

        ticket.tags.forEach(function(tag) {
            var tagTemplate = $($("#ticketContentBadgeTemplate").html());
            tagTemplate.find(".ticket-content-badge-text").text(tag.title);
            tagTemplate.css({ "color": tag.colour, "background-color": tag.backgroundcolour });
            template.find(".ticket-content-badges").append(tagTemplate);
        });

        $("#ticketContent .content").append(template);

        updateContentState("content");
    });

    // $("#ticketContent").empty();

    // updateInterfaceState("showing-content");
}

function fetchTicketsPromise(queryFilters) {
    return new Promise(function(resolve, reject) {
        global_loadingTickets = true;
        $.ajax({
            url: URL_Tickets,
            type: "GET",
            dataType: "JSON",
            data: $.param(queryFilters, true),
            success: function(response) {
                global_loadingTickets = false;
                resolve(response);
            },
            error: function(response) {
                global_loadingTickets = false;
                if (response.status === 429) {
                    alert(`
                        HTTP ${response.status} - ${response.statusText}\n
                        ${response.responseJSON.detail}
                    `);
                }
                reject(response);
            }
        });
    });
}

// Prevent certain dropdowns from closing when the user clicks.
$(".dropdown-menu.prevent-click-close").on("click", function(e) {
    e.stopPropagation();
});

function toggleComplexItems() {
    complexItems = !complexItems;

    if (complexItems) {
        $("#ticketsContainer").addClass("complex-items");
    }
    else {
        $("#ticketsContainer").removeClass("complex-items");
    }
}