var loadedServers = {};

// Returns the currently active server, or null if none are active.
function getCurrentlyActiveServer() {
    const activeServerAndId = Object.entries(loadedServers).find(([id, server]) => server.currentlyActive);
    if (activeServerAndId === undefined)
        return null;

    var [id, activeServer] = activeServerAndId;
    activeServer.id = id;

    return activeServer;
}

function addToLoadedServers(server, selectNew=true) {
    // Remove the 'id' property and add the 'currentlyActive' property
    ({id, ...rest} = server, server = {...rest, currentlyActive: false})

    // Save the server as loaded
    loadedServers[id] = server;

    // Display the loaded server
    addServerTemplate(id, server.guild_id, server.name, server.icon, server.permissions, server.owner);

    // Select the newly added server
    if (selectNew) {
        selectServer(id);
    }
}

function removeFromLoadedServers(serverPrimaryKey) {
    delete loadedServers[serverPrimaryKey];
    removeServerTemplate(serverPrimaryKey);

    $("#noSelectedServer").show();
    $("#selectedServerContainer").hide();
}

$("#serverOptionsRefreshBtn").on("click", async function() {
    await loadServerOptions();
});

// Load server options into the 'Add Server' dropdown
async function loadServerOptions() {

    // Disable controls while loading
    $("#serverOptions").prop("disabled", true);
    $("#serverOptionsRefreshBtn").prop("disabled", true).find("i.bi").addClass("spinning-360");

    // Remove existing options
    $("#serverOptions option").each(function() {
        if ($(this).val()) {
            $(this).remove();
        }
    });

    // Deselect any selected option
    $("#serverOptions").val(null).trigger("change");

    // Fetch and append the server options
    try {
        const servers = await loadGuilds();
        servers.forEach(server => {
            $("#serverOptions").append($("<option>", {
                value: server.id,
                text: server.name,
                "data-icon": server.icon,
                "data-permissions": server.permissions,
                "data-isowner": server.owner
            }));
        });
    }
    catch (error) {
        console.error(JSON.stringify(error, null, 4));
        showToast("danger", `Error Loading Guilds: HTTP ${error.status}`, error.responseJSON.message, 15000);
    }
    finally {
        // Re-enable controls
        $("#serverOptions").prop("disabled", false);
        $("#serverOptionsRefreshBtn").prop("disabled", false).find("i.bi").removeClass("spinning-360");
    }

}

// Load any existing 'saved guilds' from the database
async function loadSavedGuilds() {
    try {
        const response = await getSavedGuilds();

        response.forEach(server => {

            // 'Register' the server, by storing it for later and
            // displaying it on the server list sidebar
            addToLoadedServers(server, false);
        });
    }
    catch (error) {
        alert("Error loading saved guilds: " + error);
    }
}

// Create an element for the added server and show it
function addServerTemplate(serverPrimaryKey, serverGuildId, serverName, serverIconHash, serverPermissions, serverIsOwner) {
    template = $($("#serverItemTemplate").html());

    template.find("img").attr("src", `https://cdn.discordapp.com/icons/${serverGuildId}/${serverIconHash}.webp?size=80`);
    template.attr("data-id", serverPrimaryKey);

    // Bind the button for selecting this server
    template.find(".nav-link").off("click").on("click", function() {
        selectServer(serverPrimaryKey);
    });


    $("#serverList").prepend(template);
}

function removeServerTemplate(serverPrimaryKey) {
    $(`#serverList .server-item[data-id=${serverPrimaryKey}]`).remove();
}

// Open 'Add Server' Form Modal
$("#newServerBtn").on("click", function() {
    $("#serverFormModal").modal("show");
});

// Submit 'Add Server' Form
$("#serverForm").on("submit", async function(event) {
    event.preventDefault();

    var selectedOption = $("#serverOptions option:selected");
        serverName = selectedOption.text();
        serverGuildId = selectedOption.val();
        serverIconHash = selectedOption.attr("data-icon");
        serverPermissions = selectedOption.attr("data-permissions");
        serverIsOwner = selectedOption.attr("data-isowner");

    var serverPrimaryKey = await registerNewServer(serverName, serverGuildId, serverIconHash, serverPermissions, serverIsOwner);

    if (serverPrimaryKey !== false) {
        addToLoadedServers({
            id: serverPrimaryKey,
            name: serverName,
            guild_id: serverGuildId,
            icon: serverIconHash,
            permissions: serverPermissions,
            owner: serverIsOwner
        });
    }

    $("#serverFormModal").modal("hide");
});

// Add a new 'saved guild' based on the info provided
// returns `response.id` if successful, else false
async function registerNewServer(serverName, serverGuildId, serverIconHash, serverPermissions, serverIsOwner) {
    var formData = new FormData();
    formData.append("name", serverName);
    formData.append("guild_id", serverGuildId);
    formData.append("icon", serverIconHash);
    formData.append("added_by", currentUserId);
    formData.append("permissions", serverPermissions);
    formData.append("owner", serverIsOwner === "true");

    try { response = await newSavedGuild(formData); }
    catch (err) { return false }

    return response.id
}

function selectServer(primaryKey) {
    var server = loadedServers[primaryKey];
    
    // Change appearance of selected vs none-selected items
    $("#serverList .server-item").removeClass("active")
    $(`#serverList .server-item[data-id=${primaryKey}]`).addClass("active")    

    // Display details of the selected server
    $("#selectedServerContainer .selected-server-name").text(server.name);
    $("#selectedServerContainer .selected-server-id").text(server.guild_id);
    $("#selectedServerContainer .selected-server-icon").attr("src", `https://cdn.discordapp.com/icons/${server.guild_id}/${server.icon}.webp?size=80`);

    // Disable all loaded servers
    $.each(loadedServers, function(serverPrimaryKey, server) {
        server.currentlyActive = false;
    });

    // Activate current selected server
    loadedServers[primaryKey].currentlyActive = true;

    $("#noSelectedServer").hide();
    $("#selectedServerContainer").show();

    $(document).trigger("selectedServerChange");
}

$("#deleteSelectedServerBtn").on("click", async function() {
    var activeServer = getCurrentlyActiveServer();

    if (!activeServer) {
        showToast("danger", "Error Deleting Server", "You must select a server to delete.");
        return;
    }
    
    console.debug(`Deleting ${activeServer.id}: ${JSON.stringify(activeServer, null, 4)}`)

    try {
        await deleteSavedGuild(activeServer.id);
        removeFromLoadedServers(activeServer.id);
    }
    catch (error) {
        alert(error)
        alert(JSON.stringify(error, null, 4))
    }

});