////////////////// CONST FOR INDEX ///////////////////
const title = document.getElementById("title");
const view = document.getElementById("view");

const HomeTemplate = document.getElementById("home-template");
const installedModsTemplate = document.getElementById("installed-mods-template");
const nexusModsTemplate = document.getElementById("nexus-mods-template");
const thunderstoreModsTemplate = document.getElementById("thunderstore-mods-template");
const settingsTemplate = document.getElementById("settings-template");
const linuxSettingsTemplate = document.getElementById("settings-linux-template");
const installedModTemplate = document.getElementById("installed-mod-template");
const modTemplate = document.getElementById("mod-template");

let oldPage;
let actualTheme = [];

let searchValueNexus = "";
let searchValueInstalled = "";
let searchValueThunderstore = "";

let onlineSortFilter = "downloads";
let installedSortFilter = "name";
let thunderstoreSortFilter = "downloads";

let onlineSortOrder = "DESC";
let installedSortOrder = "ASC";
let thunderstoreSortOrder = "DESC";

let onlineOffset = 0;
let installedOffset = 0;
let thunderstoreOffset = 0;

let lastOnlineOffset = 0;
let lastInstalledOffset = 0;
let lastThunderstoreOffset = 0;

const onlineModsCount = 10;
const installedModsCount = 10;
const thunderstoreModsCount = 10;

let onlineModsTotalCount;
let installedModsTotalCount;
let thunderstoreModsTotalCount;

//////////////////////////////////////////////////////
///////////////// CONST FOR WELCOME //////////////////

let actualPage = 0;

const pageDiv = document.getElementById("page");
const buttonDiv = document.getElementById("button-div");

const oneButtonTemplate = document.getElementById("one-button-template");
const twoButtonTemplate = document.getElementById("two-button-template");

const welcomeTemplate = document.getElementById("welcome-template");
const silksongPathTemplate = document.getElementById("path-template");
const nexusTemplate = document.getElementById("nexus-template");
const styleTemplate = document.getElementById("style-template");
const linuxSettingsWelcomeTemplate = document.getElementById("settings-linux-template");

//////////////////////////////////////////////////////
////////////////////// STARTUP ///////////////////////

on_startup();

async function on_startup() {
    if ((await electronAPI.getPage()) == "index.html") {
        const theme = await files.loadTheme();
        changeTheme(theme[0], theme[1]);
        navigate("home");
    } else if ((await electronAPI.getPage()) == "welcome.html") {
        changeTheme("Silksong");
        welcomeNavigate();
    }
}

//////////////////////////////////////////////////////
///////////////////// NAVIGATE ///////////////////////

async function navigate(page) {
    if (oldPage == page) {
        return;
    }
    if (page == "refresh") {
        page = oldPage;
    }
    oldPage = page;

    view.replaceChildren();
    switch (page) {
        case "home": {
            title.innerText = "Silk Fly Launcher";
            const HomeTemplateCopy = HomeTemplate.content.cloneNode(true);
            const versionText = HomeTemplateCopy.getElementById("version-text");
            versionText.innerText = await versions.silkFlyLauncher();
            view.appendChild(HomeTemplateCopy);
            break;
        }

        case "mods-installed": {
            title.innerText = "Installed Mods";
            const installedModsTemplateCopy = installedModsTemplate.content.cloneNode(true);
            const installedModsContainer = installedModsTemplateCopy.getElementById("mods-container");
            const searchFormInstalled = installedModsTemplateCopy.getElementById("search-form");
            const searchInputInstalled = installedModsTemplateCopy.getElementById("search-input");

            searchFormInstalled.addEventListener("submit", function (event) {
                event.preventDefault();
            });
            searchInputInstalled.value = searchValueInstalled;

            view.appendChild(installedModsTemplateCopy);
            toggleSelectedListButton("sort-menu", installedSortFilter);
            setSortOrderButton();

            const { installedModsInfo, installedTotalCount } = await mods.getMods(page);
            installedModsTotalCount = installedTotalCount;
            if (installedModsInfo == []) {
                break;
            }

            for (const modInfo of installedModsInfo) {
                const installedModTemplateCopy = installedModTemplate.content.cloneNode(true);

                if (modInfo.name) {
                    const modTitleText = installedModTemplateCopy.getElementById("mod-title");
                    modTitleText.innerText = modInfo.name;
                }
                if (modInfo.author) {
                    const modAuthorText = installedModTemplateCopy.getElementById("mod-author");
                    modAuthorText.innerText = `by ${modInfo.author}`;
                }
                if (modInfo.endorsements) {
                    const modEndorsementsNumber = installedModTemplateCopy.getElementById("mod-endorsements-number");
                    if (modInfo.endorsements > 1) {
                        modEndorsementsNumber.innerText = `${modInfo.endorsements} likes`;
                    } else {
                        modEndorsementsNumber.innerText = `${modInfo.endorsements} like`;
                    }
                }
                if (modInfo.downloads) {
                    const modDownloadsNumber = installedModTemplateCopy.getElementById("mod-downloads-number");
                    if (modInfo.downloads > 1) {
                        modDownloadsNumber.innerText = `${modInfo.downloads} downloads`;
                    } else {
                        modDownloadsNumber.innerText = `${modInfo.downloads} download`;
                    }
                }
                if (modInfo.summary) {
                    const modDescriptionText = installedModTemplateCopy.getElementById("mod-description");
                    modDescriptionText.innerText = modInfo.summary;
                }
                if (modInfo.pictureUrl) {
                    const modPicture = installedModTemplateCopy.getElementById("mod-icon");
                    modPicture.src = modInfo.pictureUrl;
                }
                if (modInfo.version || modInfo.updatedAt) {
                    let text = "";
                    if (modInfo.version) {
                        text = text.concat(`V${modInfo.version} `);
                    }
                    if (modInfo.updatedAt) {
                        text = text.concat(`last updated on ${modInfo.updatedAt.slice(0, 10)}`);
                    }
                    const modVersionText = installedModTemplateCopy.getElementById("mod-version");
                    modVersionText.innerText = text;
                }

                const isActivatedCheckbox = installedModTemplateCopy.getElementById("activated-mod");
                if (modInfo.activated) {
                    isActivatedCheckbox.checked = true;
                }

                isActivatedCheckbox.addEventListener("change", async function () {
                    if (this.checked) {
                        mods.activateMods(modInfo.modId);
                        searchInstalledMods();
                    } else {
                        mods.deactivateMods(modInfo.modId);
                        searchInstalledMods();
                    }
                });

                if (modInfo.source && modInfo.source != "local") {
                    const modSource = installedModTemplateCopy.getElementById("mod-source");
                    modSource.innerText = `From ${modInfo.source}`;

                    const modUrls = {
                        nexusmods: `https://www.nexusmods.com/hollowknightsilksong/mods/${modInfo.modId}`,
                        thunderstore: `https://new.thunderstore.io/c/hollow-knight-silksong/p/${modInfo.author}/${modInfo.name}`,
                    };

                    const modLinkButton = installedModTemplateCopy.getElementById("external-link");
                    modLinkButton.href = modUrls[modInfo.source];
                    modLinkButton.addEventListener("click", function (event) {
                        event.preventDefault();
                        const modLink = modLinkButton.href;
                        electronAPI.openExternalLink(modLink);
                    });
                } else {
                    const modLinkButton = installedModTemplateCopy.getElementById("external-link");
                    modLinkButton.remove();
                }

                const uninstallModButton = installedModTemplateCopy.getElementById("uninstall-mod-button");
                uninstallModButton.addEventListener("click", async function (event) {
                    event.preventDefault();
                    await mods.uninstall(modInfo.modId);

                    navigate("refresh");
                });

                installedModsContainer.appendChild(installedModTemplateCopy);
            }

            break;
        }

        case "mods-online": {
            title.innerText = "Nexus Mods";
            const onlineModsTemplateCopy = nexusModsTemplate.content.cloneNode(true);
            const ModsContainer = onlineModsTemplateCopy.getElementById("mods-container");
            const searchFormNexus = onlineModsTemplateCopy.getElementById("search-form");
            const searchInputNexus = onlineModsTemplateCopy.getElementById("search-input");

            searchFormNexus.addEventListener("submit", async function (event) {
                event.preventDefault();
            });
            searchInputNexus.value = searchValueNexus;

            view.appendChild(onlineModsTemplateCopy);
            toggleSelectedListButton("sort-menu", onlineSortFilter);
            setSortOrderButton();

            const { onlineModsInfo, onlineTotalCount } = await mods.getMods(page);
            onlineModsTotalCount = onlineTotalCount;
            if (onlineModsInfo == undefined) {
                break;
            }
            for (const mod of onlineModsInfo) {
                if (mod.name == undefined) {
                    continue;
                }
                const modTemplateCopy = modTemplate.content.cloneNode(true);
                if (mod.name) {
                    const modTitleText = modTemplateCopy.getElementById("mod-title");
                    modTitleText.innerText = mod.name;
                }
                if (mod.author) {
                    const modAuthorText = modTemplateCopy.getElementById("mod-author");
                    modAuthorText.innerText = `by ${mod.author}`;
                }
                if (mod.endorsements) {
                    const modEndorsementsNumber = modTemplateCopy.getElementById("mod-endorsements-number");
                    if (mod.endorsements > 1) {
                        modEndorsementsNumber.innerText = `${mod.endorsements} likes`;
                    } else {
                        modEndorsementsNumber.innerText = `${mod.endorsements} like`;
                    }
                }
                if (mod.downloads) {
                    const modDownloadsNumber = modTemplateCopy.getElementById("mod-downloads-number");
                    if (mod.downloads > 1) {
                        modDownloadsNumber.innerText = `${mod.downloads} downloads`;
                    } else {
                        modDownloadsNumber.innerText = `${mod.downloads} download`;
                    }
                }
                if (mod.summary) {
                    const modDescriptionText = modTemplateCopy.getElementById("mod-description");
                    modDescriptionText.innerText = mod.summary;
                }
                if (mod.pictureUrl) {
                    const modPicture = modTemplateCopy.getElementById("mod-icon");
                    modPicture.src = mod.pictureUrl;
                }
                if (mod.version && mod.updatedAt) {
                    const modVersionText = modTemplateCopy.getElementById("mod-version");
                    modVersionText.innerText = `V${mod.version} last updated on ${mod.updatedAt.slice(0, 10)}`;
                }

                const modUrl = `https://www.nexusmods.com/hollowknightsilksong/mods/${mod.modId}`;

                const modLinkButton = modTemplateCopy.getElementById("external-link");
                modLinkButton.href = modUrl;
                modLinkButton.addEventListener("click", function (event) {
                    event.preventDefault();
                    const modLink = modLinkButton.href;
                    electronAPI.openExternalLink(modLink);
                });

                const modDownloadButton = modTemplateCopy.getElementById("download-mod-button");
                modDownloadButton.addEventListener("click", function (event) {
                    event.preventDefault();
                    const modDownloadLink = `${modUrl}?tab=files`;
                    nexus.download(modDownloadLink);
                });

                ModsContainer.appendChild(modTemplateCopy);
            }
            break;
        }

        case "mods-thunderstore": {
            title.innerText = "Thunderstore Mods";
            const thunderstoreModsTemplateCopy = thunderstoreModsTemplate.content.cloneNode(true);
            const thunderstoreModsContainer = thunderstoreModsTemplateCopy.getElementById("mods-container");
            const searchFormThunderstore = thunderstoreModsTemplateCopy.getElementById("search-form");
            const searchInputThunderstore = thunderstoreModsTemplateCopy.getElementById("search-input");

            searchFormThunderstore.addEventListener("submit", async function (event) {
                event.preventDefault();
            });
            searchInputThunderstore.value = searchValueThunderstore;

            view.appendChild(thunderstoreModsTemplateCopy);
            toggleSelectedListButton("sort-menu", thunderstoreSortFilter);
            setSortOrderButton();

            const { thunderstoreModsInfo, thunderstoreTotalCount } = await mods.getMods(page);
            thunderstoreModsTotalCount = thunderstoreTotalCount;
            if (thunderstoreModsInfo == undefined) {
                break;
            }
            for (const mod of thunderstoreModsInfo) {
                if (mod.name == undefined) {
                    continue;
                }
                const modTemplateCopy = modTemplate.content.cloneNode(true);
                if (mod.name) {
                    const modTitleText = modTemplateCopy.getElementById("mod-title");
                    modTitleText.innerText = mod.name.replaceAll("_", " ");
                }
                if (mod.author) {
                    const modAuthorText = modTemplateCopy.getElementById("mod-author");
                    modAuthorText.innerText = `by ${mod.author}`;
                }
                if (mod.endorsements) {
                    const modEndorsementsNumber = modTemplateCopy.getElementById("mod-endorsements-number");
                    if (mod.endorsements > 1) {
                        modEndorsementsNumber.innerText = `${mod.endorsements} likes`;
                    } else {
                        modEndorsementsNumber.innerText = `${mod.endorsements} like`;
                    }
                }
                if (mod.downloads) {
                    const modDownloadsNumber = modTemplateCopy.getElementById("mod-downloads-number");
                    if (mod.downloads > 1) {
                        modDownloadsNumber.innerText = `${mod.downloads} downloads`;
                    } else {
                        modDownloadsNumber.innerText = `${mod.downloads} download`;
                    }
                }
                if (mod.summary) {
                    const modDescriptionText = modTemplateCopy.getElementById("mod-description");
                    modDescriptionText.innerText = mod.summary;
                }
                if (mod.pictureUrl) {
                    const modPicture = modTemplateCopy.getElementById("mod-icon");
                    modPicture.src = mod.pictureUrl;
                }
                if (mod.version && mod.updatedAt) {
                    const modVersionText = modTemplateCopy.getElementById("mod-version");
                    modVersionText.innerText = `V${mod.version} last updated on ${mod.updatedAt.slice(0, 10)}`;
                }

                const modUrl = `https://new.thunderstore.io/c/hollow-knight-silksong/p/${mod.author}/${mod.name}`;

                const modLinkButton = modTemplateCopy.getElementById("external-link");
                modLinkButton.href = modUrl;
                modLinkButton.addEventListener("click", function (event) {
                    event.preventDefault();
                    const modLink = modLinkButton.href;
                    electronAPI.openExternalLink(modLink);
                });

                const modDownloadButton = modTemplateCopy.getElementById("download-mod-button");
                modDownloadButton.addEventListener("click", function (event) {
                    event.preventDefault();
                    const modDownloadLink = `https://thunderstore.io/package/download/${mod.author}/${mod.name}/${mod.version}`;
                    thunderstore.download(modDownloadLink, mod.modId);
                });

                thunderstoreModsContainer.appendChild(modTemplateCopy);
            }
            break;
        }
        case "general-settings": {
            title.innerText = "Settings";
            const settingsTemplateCopy = settingsTemplate.content.cloneNode(true);
            const linuxSettingsTemplateCopy = linuxSettingsTemplate.content.cloneNode(true);
            const silksongPathInput = settingsTemplateCopy.getElementById("silksong-path-input");
            const nexusAPIForm = settingsTemplateCopy.getElementById("nexus-api-form");
            const versionsList = settingsTemplateCopy.getElementById("versions-list");
            const versionsDictionnary = {
                "Silk-Fly-Launcher": `Silk Fly Launcher: v${await versions.silkFlyLauncher()}`,
                Electron: `Electron: v${versions.electron()}`,
                Node: `Node.js: v${versions.node()}`,
                Chromium: `Chromium: v${versions.chromium()}`,
            };
            const lacePinCheckbox = settingsTemplateCopy.getElementById("lace-pin");

            silksongPathInput.value = await files.loadSilksongPath();
            silksongPathInput.addEventListener("input", async function () {
                const silksongPath = silksongPathInput.value;
                files.saveSilksongPath(silksongPath);
            });

            nexusAPIForm.addEventListener("submit", function (event) {
                event.preventDefault();
            });

            for (const element of versionsList.children) {
                element.innerText = versionsDictionnary[element.id];
            }

            const theme = await files.loadTheme();
            lacePinCheckbox.checked = theme[1];

            lacePinCheckbox.addEventListener("change", async function () {
                if (this.checked) {
                    const theme = await files.loadTheme();
                    changeTheme(theme[0], true);
                    toggleThemesMenu();
                } else {
                    const theme = await files.loadTheme();
                    changeTheme(theme[0], false);
                    toggleThemesMenu();
                }
            });

            view.appendChild(settingsTemplateCopy);
            setBepinexVersion();
            setThemeButton();
            toggleSelectedListButton("themes-menu", actualTheme[0]);
            setNexusAPI();
            if (electronAPI.getOS() == "linux") {
                const linuxSteamCheckbox = linuxSettingsTemplateCopy.getElementById("linux-steam");

                linuxSteamCheckbox.checked = await files.loadLinuxSteam();
                linuxSteamCheckbox.addEventListener("change", async function () {
                    files.saveLinuxSteam(this.checked);
                });

                view.appendChild(linuxSettingsTemplateCopy);
            }
            break;
        }
    }
}

async function welcomeNavigate() {
    pageDiv.replaceChildren();
    switch (actualPage) {
        case 0:
            pageDiv.appendChild(welcomeTemplate.content.cloneNode(true));
            buttonDiv.replaceChildren();
            buttonDiv.appendChild(oneButtonTemplate.content.cloneNode(true));
            break;

        case 1: {
            pageDiv.appendChild(silksongPathTemplate.content.cloneNode(true));
            buttonDiv.replaceChildren();
            buttonDiv.appendChild(twoButtonTemplate.content.cloneNode(true));

            const silksongPathInput = document.getElementById("silksong-path-input");
            if ((await files.loadSilksongPath()) == "") {
                autoDetectGamePath();
            } else {
                document.getElementById("silksong-path-input").value = await files.loadSilksongPath();
            }

            silksongPathInput.addEventListener("input", async function () {
                const silksongPath = silksongPathInput.value;
                await files.saveSilksongPath(silksongPath);
            });
            break;
        }
        case 2: {
            pageDiv.appendChild(styleTemplate.content.cloneNode(true));
            toggleSelectedListButton("themes-menu", actualTheme[0]);
            break;
        }
        case 3: {
            pageDiv.appendChild(nexusTemplate.content.cloneNode(true));
            const nexusLink = document.getElementById("external-link");
            const nexusAPIForm = document.getElementById("nexus-api-form");

            nexusLink.addEventListener("click", function (event) {
                event.preventDefault();
                const url = nexusLink.href;
                electronAPI.openExternalLink(url);
            });

            nexusAPIForm.addEventListener("submit", function (event) {
                event.preventDefault();
            });
            setNexusAPI();
            break;
        }
        case 4: {
            if (electronAPI.getOS() == "linux") {
                const linuxSettingsWelcomeTemplateCopy = linuxSettingsWelcomeTemplate.content.cloneNode(true);
                const linuxSteamCheckbox = linuxSettingsWelcomeTemplateCopy.getElementById("linux-steam");

                linuxSteamCheckbox.checked = await files.loadLinuxSteam();
                linuxSteamCheckbox.addEventListener("change", async function () {
                    files.saveLinuxSteam(this.checked);
                });

                pageDiv.appendChild(linuxSettingsWelcomeTemplateCopy);
            } else {
                electronAPI.loadMainPage();
            }
            break;
        }
        case 5: {
            electronAPI.loadMainPage();
            break;
        }
    }
}

function next() {
    actualPage++;
    welcomeNavigate();
}

function back() {
    actualPage--;
    welcomeNavigate();
}

//////////////////////////////////////////////////////
/////////////////// DATA HANDLING ////////////////////

async function initialImportData() {
    if (await files.import()) {
        electronAPI.loadMainPage();
    }
}

async function importData() {
    await files.import();
    document.getElementById("silksong-path-input").value = await files.loadSilksongPath();
    const lacePinCheckbox = document.getElementById("lace-pin");
    const theme = await files.loadTheme();
    lacePinCheckbox.checked = theme[1];
    changeTheme(theme[0]);
    toggleThemesMenu();
}

async function exportData() {
    await files.export();
}

async function deleteData() {
    const lacePinCheckbox = document.getElementById("lace-pin");
    lacePinCheckbox.checked = false;
    changeTheme("Silksong");
    toggleThemesMenu();
    await files.delete();
    document.getElementById("silksong-path-input").value = await files.loadSilksongPath();
}

//////////////////////////////////////////////////////
////////////////////// BEPINEX ///////////////////////

async function installBepinex() {
    await bepinex.install();
    setBepinexVersion();
}

async function uninstallBepinex() {
    await bepinex.uninstall();
    setBepinexVersion();
}

async function backupBepinex() {
    await bepinex.backup();
    setBepinexVersion();
}

async function deleteBepinexBackup() {
    await bepinex.deleteBackup();
    setBepinexVersion();
}

async function setBepinexVersion() {
    const bepinexVersionText = document.getElementById("bepinex-version-text");
    const bepinexInstallButton = document.getElementById("install-bepinex-button");
    if (bepinexVersionText == undefined) {
        return;
    }

    const bepinexVersion = await files.loadBepinexVersion();
    const bepinexBackupVersion = await files.loadBepinexBackupVersion();
    if (bepinexVersion == undefined) {
        if (bepinexBackupVersion == undefined) {
            bepinexVersionText.innerText = "BepInEx is not installed";
        } else {
            bepinexVersionText.innerText = `BepInEx ${bepinexBackupVersion} is backed up`;
        }
        bepinexInstallButton.innerText = "Install";
    } else {
        bepinexVersionText.innerText = `BepInEx ${bepinexVersion} is installed`;
        bepinexInstallButton.innerText = "Update";
    }
}

async function searchInstalledMods() {
    const searchInput = document.getElementById("search-input");
    searchValueInstalled = searchInput.value;
    await mods.searchInstalled(searchValueInstalled, installedOffset, installedModsCount, installedSortFilter, installedSortOrder);
    await navigate("refresh");
}

//////////////////////////////////////////////////////
//////////////// NEXUS / THUNDERSTORE ////////////////

async function verifyNexusAPI() {
    const response = await nexus.verifyAPI();

    const nexusCheckImage = document.getElementById("nexus-check-image");
    if (nexusCheckImage == undefined) {
        return;
    }

    if (response) {
        nexusCheckImage.src = "assets/icons/check.svg";
    } else {
        nexusCheckImage.src = "assets/icons/cross.svg";
    }
}

async function searchNexusMods() {
    let searchInput = document.getElementById("search-input");
    searchValueNexus = searchInput.value;
    await nexus.search(searchValueNexus, onlineOffset, onlineModsCount, onlineSortFilter, onlineSortOrder);
    await navigate("refresh");
    searchInput = document.getElementById("search-input");
    searchInput.value = searchValueNexus;
}

async function setNexusAPI() {
    const nexusAPIInput = document.getElementById("nexus-api-input");
    const secretString = "●".repeat(1000);
    if (!(await files.loadNexusAPI())) {
        if (nexusAPIInput.value && nexusAPIInput.value != secretString) {
            await files.saveNexusAPI(nexusAPIInput.value);
            nexusAPIInput.value = secretString;
            nexusAPIInput.readOnly = true;
        } else {
            nexusAPIInput.value = "";
            nexusAPIInput.readOnly = false;
        }
    } else {
        nexusAPIInput.value = secretString;
        nexusAPIInput.readOnly = true;
    }
    verifyNexusAPI();
}

async function resetNexusAPI() {
    if (await files.loadNexusAPI()) {
        await files.saveNexusAPI(undefined);
        setNexusAPI();
    }
}

async function searchThunderstoreMods() {
    let searchInput = document.getElementById("search-input");
    searchValueThunderstore = searchInput.value;
    await thunderstore.search(searchValueThunderstore, thunderstoreOffset, thunderstoreModsCount, thunderstoreSortFilter, thunderstoreSortOrder);
    await navigate("refresh");
    searchInput = document.getElementById("search-input");
    searchInput.value = searchValueThunderstore;
}

async function addOfflineMod() {
    await mods.add();
    searchInstalledMods();
}

//////////////////////////////////////////////////////
//////////////// THEMES / SORT / LIST ////////////////

function toggleThemesMenu() {
    const themesMenu = document.getElementById("themes-menu");
    if (themesMenu) {
        themesMenu.classList.toggle("show");
    }
}

async function setThemeButton() {
    const themesButton = document.getElementById("themes-button");
    if (themesButton) {
        const theme = await files.loadTheme();
        themesButton.textContent = theme[0];
    }
}

function changeTheme(theme, state) {
    toggleThemesMenu();
    toggleSelectedListButton("themes-menu", theme);

    const lacePinCheckbox = document.getElementById("lace-pin");
    if (lacePinCheckbox) {
        lacePinState = lacePinCheckbox.checked;
    } else if (state) {
        lacePinState = state;
    } else {
        lacePinState = false;
    }

    if (actualTheme[0] == theme && actualTheme[1] == lacePinState) {
        return;
    }
    actualTheme = [theme, lacePinState];

    files.saveTheme(theme, lacePinState);

    setThemeButton();

    // prettier-ignore
    /* eslint-disable */
    const themesColors = {
        "var":             ["--primary-color", "--secondary-color", "--background-color"],
        "Silksong":        ["rgba(255, 25,  0,   0.3)", "#ff6b6b", "rgba(255, 72,  0,   0.2)"],
        "Citadel of song": ["rgba(160, 116, 89,  0.3)", "#d3ba91", "rgba(123, 102, 93,  0.2)"],
        "Cradle":          ["rgba(123, 136, 255, 0.3)", "#7c9fea", "rgba(61,  88,  150, 0.2)"],
        "Abyss":           ["rgba(255, 255, 255, 0.3)", "#ececec", "rgba(255, 255, 255, 0.2)"],
        "Greyroot":        ["rgba(181, 255, 180, 0.3)", "#c1ffcd", "rgba(90,  165, 130, 0.2)"],
        "Surface":         ["rgba(75,  120, 255, 0.3)", "#87c3ff", "rgba(42,  107, 203, 0.2)"],
        "Steel":           ["rgba(164, 164, 164, 0.3)", "#c5b9b9", "rgba(255, 255, 255, 0.2)"]
    };
    /* eslint-enable */

    for (let i = 0; i < 3; i++) {
        document.documentElement.style.setProperty(themesColors.var[i], themesColors[theme][i]);
    }

    const backgroundVideo = document.getElementById("background-video");
    let backgroundVideoPath = `assets/background/${theme}.mp4`;
    if (lacePinState) {
        backgroundVideoPath = `assets/background/${theme} Lace Pin.mp4`;
    }

    backgroundVideo.src = backgroundVideoPath;
}

function toggleSortMenu() {
    const sortMenu = document.getElementById("sort-menu");
    if (sortMenu) {
        sortMenu.classList.toggle("show");
    }
}

function setSortOrderButton() {
    let sortOrder;
    if (oldPage == "mods-installed") {
        sortOrder = installedSortOrder;
    } else if (oldPage == "mods-online") {
        sortOrder = onlineSortOrder;
    } else if (oldPage == "mods-thunderstore") {
        sortOrder = thunderstoreSortOrder;
    }

    const sortOrderButton = document.getElementById("sort-order-image");
    if (sortOrderButton) {
        if (sortOrder == "ASC") {
            sortOrderButton.src = "assets/icons/sort-order-2.svg";
        } else {
            sortOrderButton.src = "assets/icons/sort-order-1.svg";
        }
    }
}

function changeSort(sortFilterParameter) {
    toggleSortMenu();
    toggleSelectedListButton("sort-menu", sortFilterParameter);

    if (oldPage == "mods-installed") {
        installedSortFilter = sortFilterParameter;
        searchInstalledMods();
    } else if (oldPage == "mods-online") {
        onlineSortFilter = sortFilterParameter;
        searchNexusMods();
    } else if (oldPage == "mods-thunderstore") {
        thunderstoreSortFilter = sortFilterParameter;
        searchThunderstoreMods();
    }
}

function inverseSort() {
    if (oldPage == "mods-installed") {
        if (installedSortOrder == "ASC") {
            installedSortOrder = "DESC";
        } else {
            installedSortOrder = "ASC";
        }
        searchInstalledMods();
    } else if (oldPage == "mods-online") {
        if (onlineSortOrder == "ASC") {
            onlineSortOrder = "DESC";
        } else {
            onlineSortOrder = "ASC";
        }
        searchNexusMods();
    } else if (oldPage == "mods-thunderstore") {
        if (thunderstoreSortOrder == "ASC") {
            thunderstoreSortOrder = "DESC";
        } else {
            thunderstoreSortOrder = "ASC";
        }
        searchThunderstoreMods();
    }
}

function toggleSelectedListButton(ListMenuId, buttonId) {
    const themesMenu = document.getElementById(ListMenuId);
    if (themesMenu) {
        Array.from(themesMenu.children).forEach((child) => {
            child.classList.remove("selected");
        });
    }

    const themesButton = document.getElementById(buttonId);
    if (themesButton) {
        themesButton.classList.toggle("selected");
    }
}

//////////////////////////////////////////////////////
//////////////////// UNCATEGORIZE ////////////////////

async function launch(mode) {
    await electronAPI.launchGame(mode);
    setBepinexVersion();
}

async function autoDetectGamePath() {
    await files.autoDetectGamePath();
    if (document.getElementById("silksong-path-input")) {
        document.getElementById("silksong-path-input").value = await files.loadSilksongPath();
    }
}

function showToast(message, type = "info", duration = 3000) {
    const toastDiv = document.getElementById("toast-div");
    const toast = document.createElement("p");

    toast.classList.add("toast", type);
    toast.innerText = message;
    toastDiv.appendChild(toast);
    toast.classList.add("show");

    setTimeout(() => {
        toast.classList.remove("show");
        toast.addEventListener("transitionend", () => toast.remove());
    }, duration);
}

electronAPI.onShowToast(showToast);

function showBanner(message) {
    const bannerDiv = document.getElementById("banner-div");
    const bannerText = document.getElementById("banner-text");

    bannerText.innerHTML = message;
    bannerDiv.classList.add("show");
}

electronAPI.onShowBanner(showBanner);

function hideBanner() {
    const bannerDiv = document.getElementById("banner-div");
    bannerDiv.classList.remove("show");
}

function changeModsPage(offsetChange) {
    if (oldPage == "mods-installed") {
        if (offsetChange == "min") {
            installedOffset = 0;
        } else if (offsetChange == "max") {
            installedOffset = installedModsTotalCount;
        } else {
            installedOffset += installedModsCount * offsetChange;
            installedOffset = clamp(installedOffset, 0, installedModsTotalCount);
        }
        installedOffset = Math.floor(installedOffset / 10) * 10;
        if (lastInstalledOffset != installedOffset) {
            lastInstalledOffset = installedOffset;
            searchInstalledMods();
        }
    } else if (oldPage == "mods-online") {
        if (offsetChange == "min") {
            onlineOffset = 0;
        } else if (offsetChange == "max") {
            onlineOffset = onlineModsTotalCount;
        } else {
            onlineOffset += onlineModsCount * offsetChange;
            onlineOffset = clamp(onlineOffset, 0, onlineModsTotalCount);
        }
        onlineOffset = Math.floor(onlineOffset / 10) * 10;
        if (lastOnlineOffset != onlineOffset) {
            lastOnlineOffset = onlineOffset;
            searchNexusMods();
        }
    } else if (oldPage == "mods-thunderstore") {
        if (offsetChange == "min") {
            thunderstoreOffset = 0;
        } else if (offsetChange == "max") {
            thunderstoreOffset = thunderstoreModsTotalCount;
        } else {
            thunderstoreOffset += thunderstoreModsCount * offsetChange;
            thunderstoreOffset = clamp(thunderstoreOffset, 0, thunderstoreModsTotalCount);
        }
        thunderstoreOffset = Math.floor(thunderstoreOffset / 10) * 10;
        if (lastThunderstoreOffset != thunderstoreOffset) {
            lastThunderstoreOffset = thunderstoreOffset;
            searchThunderstoreMods();
        }
    }
}

function clamp(number, min, max) {
    return Math.max(min, Math.min(number, max));
}
