

import { neoError } from "./_global--log.js";
import { observeOnce, observeClick } from "./_global--observer.js";
import { fetchEndpoint } from "./_global--endpoint.js";
import { reloadPage } from "./_global-reload-page.js";
import Swal from "./_global-sweetalert2.js";
import { neo__ } from "./_global--translation.js";
import { jsVar } from "./_global--enqueue-loader.js";
import { DomNodeHelper } from "./_global--dom-node-helper.js";
import { extractJson } from "./_global--extract-json.js";
import { neoLoadInterfaceFunc } from "./_global--interface.js";




let pluginInfos;
let initialSwitchStates = {};
async function updatePluginDetails() {

    pluginInfos = await fetchEndpoint("/wp-json/neo/neo-manager-installer--plugin-info").then(extractJson);

    for (const switchNode of document.querySelectorAll("neo-switch-neo-draw-full.neo-manager-installer--plugin-active-switch")) {
        if (switchNode.loading) { continue; }

        const pluginSlug = switchNode.getAttribute("data-neo-manager-installer--plugin-slug");
        const pluginEntryFileRel = switchNode.getAttribute("data-neo-manager-installer--entry-file-rel");
        const tooltipContentNode = document.querySelector(`.neo-manager-installer--tooltip[data-neo-manager-installer--plugin-slug="${pluginSlug}"]`);
        const installOptionsDropdownNode = document.querySelector(`.neo-manager-installer--install-options[data-neo-manager-installer--plugin-slug="${pluginSlug}"]`);

        let activePluginSlug = null, activeVersion = null, activeEdition = null;

        for (const activeNeoplugin of pluginInfos.activeNeoplugins) {
            if (!(activeNeoplugin["slug"] === pluginSlug || activeNeoplugin["module_files"][pluginSlug])) { continue; }
            activeEdition    = activeNeoplugin["edition"] ?? "?";
            activeVersion    = activeNeoplugin["version"] ?? "?";
            activePluginSlug = activeNeoplugin["slug"]    ?? "?";
            if (activePluginSlug === pluginSlug) { activePluginSlug = null; }
            break;
        }
        if (pluginInfos.suppressedPlugins.includes(pluginSlug)) { activePluginSlug = null; activeVersion = null; activeEdition = null; }

        const isPluginModuleAvailable = pluginInfos.activeNeoplugins.some((activeNeoPlugin) => activeNeoPlugin["slug"] === pluginSlug || (activeNeoPlugin["existing_modules"] ?? []).includes(pluginSlug));
        switchNode.checked = Boolean(activeVersion);
        switchNode.disabled = Boolean(
            ((pluginInfos.pluginList.find((plugin) => plugin["plugin-slug"] === pluginSlug)?.["plugin-is-coming-soon"] ?? false) && !isPluginModuleAvailable) ||
            (installOptionsDropdownNode && !pluginInfos.installedPlugins[pluginEntryFileRel]                                     && !isPluginModuleAvailable)
        );
        initialSwitchStates[pluginSlug] ??= switchNode.checked;

        await (await neoLoadInterfaceFunc("neo-draw", "neo-settings--settings-section-control.js", "interfaceForceHideSettings20260327"))(pluginSlug, !activeVersion);

        const reloadButtonWrapperNode = document.querySelector(`.neo-manager-installer--reload-button-wrapper[data-neo-manager-installer--plugin-slug="${pluginSlug}"]`);
        if (!initialSwitchStates[pluginSlug] && switchNode.checked) {
            const pluginName = pluginInfos.pluginList.find((plugin) => plugin["plugin-slug"] === pluginSlug)?.["plugin-name"] ?? pluginSlug;
            reloadButtonWrapperNode.innerHTML = `<neo-info-tooltip-neo-draw-full>
                <button slot="icon" style="border:none;background:transparent;font-size:1em;color:#606060;cursor:pointer;">♻️&nbsp;<span style="text-decoration:underline;">${neo__("Reload", "Neu laden")}</span></button>
                <span>${neo__(`Click to reload the page and show the settings of ${pluginName}.`, `Klicken, um die Seite neuzuladen und die Einstellungen von ${pluginName} anzuzeigen.`)}</span>
            </neo-info-tooltip-neo-draw-full>`;
            observeClick(reloadButtonWrapperNode.querySelector("button"), () => { reloadPage(); });
        } else { reloadButtonWrapperNode.innerHTML = ""; }

        switchNode.setAttribute("data-neo-manager-installer--will-install-plugin", String(!isPluginModuleAvailable && !pluginInfos.installedPlugins[pluginEntryFileRel]));

        let tooltipHtml = '<ul style="list-style-type: none; padding-left: 0; margin: 0;">';
        if (activeVersion) {
            if (activePluginSlug) { tooltipHtml += "<li>" + neo__("Executed by:", "Ausgeführt durch:") + " " + "<strong>" + activePluginSlug + "</strong>" + "</li>"; }
            tooltipHtml += "<li>" + neo__("Edition: ", "Edition: ") + "<strong>" + activeEdition.replace("wporg", "WP.org") + "</strong>" + "</li>";
            tooltipHtml += "<li>" + neo__("Version: ", "Version: ") + "<strong>" + activeVersion + "</strong>" + "</li>";
            const newestVersion = pluginInfos.pluginList.find((plugin) => plugin["plugin-slug"] === pluginSlug)?.["newest-version"] ?? null;
            if (newestVersion && newestVersion !== activeVersion && !activeVersion.includes(".l")) { tooltipHtml += "<li>" + neo__("Update: ", "Update: ") + "<strong>" + newestVersion + "</strong>" + "</li>"; }
        }
        if (activeVersion && pluginInfos.pluginList.find((plugin) => plugin["plugin-slug"] === pluginSlug)?.["plugin-changelog-url"]) { tooltipHtml += "<li>" + `<a target="_blank" rel="noopener" href="${pluginInfos.pluginList.find((plugin) => plugin["plugin-slug"] === pluginSlug)?.["plugin-changelog-url"]}">${neo__("Changelog", "Changelog")}</a>` + "</li>"; }
        if (pluginInfos.pluginList.find((plugin) => plugin["plugin-slug"] === pluginSlug)?.["plugin-website-url"]) { tooltipHtml += "<li>" + `<a target="_blank" rel="noopener" href="${pluginInfos.pluginList.find((plugin) => plugin["plugin-slug"] === pluginSlug)?.["plugin-website-url"]}">${neo__("Website", "Webseite")}</a>` + "</li>"; }
        tooltipContentNode.innerHTML = tooltipHtml;

        if (installOptionsDropdownNode) {

            installOptionsDropdownNode.innerHTML = "";
            let isOptionSelected = false;
            for (const editionBundle of pluginInfos.pluginList.find((plugin) => plugin["plugin-slug"] === pluginSlug)?.["plugin-bundles"] ?? []) {
                for (const version of editionBundle["versions"]) {
                    const isSelected = (
                        (activeVersion === version && !activeVersion?.includes(".a") && !activeVersion?.includes(".l")) ||
                        (activeVersion?.includes(".a") && version === "Alpha") ||
                        (activeVersion?.includes(".l") && version === "Live")
                    ) && activeEdition === editionBundle["edition"];
                    isOptionSelected ||= isSelected;
                    installOptionsDropdownNode.appendChild(new DomNodeHelper(`<option value="${editionBundle["edition"]},${version}" ${isSelected ? "selected" : ""}>${editionBundle["edition"]} - ${version}${isSelected ? neo__(" (current)", "(aktuell)") : ""}</option>`).getNode());
                }
            }

                 if (!isOptionSelected && activeVersion !== null) { installOptionsDropdownNode.appendChild(new DomNodeHelper(`<option value="${activeEdition},${activeVersion}" disabled selected>${activePluginSlug ? `${activePluginSlug} - ` : ""}${activeEdition} - ${activeVersion} ${neo__(" (current)", "(aktuell)")}</option>`).getNode()); }
            else if (!isOptionSelected)                           { installOptionsDropdownNode.appendChild(new DomNodeHelper(`<option value="" disabled selected>${neo__("Not activated", "Nicht aktiviert")}</option>`).getNode()); }
        }
    }
}
updatePluginDetails();


async function activateOrDeactivatePlugin(activate, pluginSlug, isInstallButtonPressed = false) {
    if (!pluginSlug) { throw new Error("Plugin slug is required"); }
    const switchNode = document.querySelector(`neo-switch-neo-draw-full.neo-manager-installer--plugin-active-switch[data-neo-manager-installer--plugin-slug="${pluginSlug}"]`);
    const installOptionsDropdownNode = document.querySelector(`.neo-manager-installer--install-options[data-neo-manager-installer--plugin-slug="${pluginSlug}"]`);

    let edition, version;
    if (installOptionsDropdownNode) { [edition, version] = installOptionsDropdownNode.value.split(","); }

    if (activate && !isInstallButtonPressed && switchNode.getAttribute("data-neo-manager-installer--will-install-plugin") === "true") {
        const pluginName = pluginInfos.pluginList.find((plugin) => plugin["plugin-slug"] === pluginSlug)?.["plugin-name"] ?? pluginSlug;
        const confirmResult = await Swal.fire({
            icon: "question",
            text: neo__(`The plugin ${pluginName} will be installed.`, `Das Plugin ${pluginName} wird installiert.`),
            showCancelButton: true, confirmButtonText: neo__("Install", "Installieren"), cancelButtonText: neo__("Cancel", "Abbrechen"),
        });
        if (!confirmResult.isConfirmed) { throw new Error("abort"); }
    }

    try {

        const resp = await fetchEndpoint("/wp-json/neo/neo-manager-installer--install", {
            method: "POST",
            body: { "action": activate ? "activate" : "deactivate", "plugin-slug": pluginSlug, "edition": edition, "version": version, "is-install-button-pressed": isInstallButtonPressed }
        });
        const respText = await resp.text();
        if (respText.includes("Download failed")) {
            neoError("Error downloading plugin", respText);
            throw new Error("Error downloading plugin");
        }

        switchNode.loading = false;
        await updatePluginDetails();
    } catch (err) {
        if (err.message !== "abort") {

            if (activate && (version === "Live" || version === "Alpha")) {
                const bundlerAvailableResp = await fetch(jsVar("neoManagerInstallerBundlerAvailableRestUrl"));
                if (!bundlerAvailableResp.ok) {
                    Swal.fire({
                        icon: "error", title: neo__("Error", "Fehler"),
                        text: neo__("To install alpha/live version, you need an active neoBundler on the prod-server (e.g. with neoProd).", "Um die Alpha/Live-Version zu installieren, benötigst du einen aktiven neoBundler auf dem Prod-Server (z.B. mit neoProd)."),
                    });
                    throw err;
                }
            }
            Swal.fire({ icon: "error", title: "Error", text: err.message });
        }
        throw err;
    }
}


observeOnce("neo-switch-neo-draw-full.neo-manager-installer--plugin-active-switch", (switchCellNode) => {
    switchCellNode.onchange = async ({ checked }) => {
        const pluginSlug = switchCellNode.getAttribute("data-neo-manager-installer--plugin-slug");
        await activateOrDeactivatePlugin(checked, pluginSlug, false);
    };
});


observeOnce(".neo-manager-installer--install-options", (dropdownNode) => {
    const pluginSlug = dropdownNode.getAttribute("data-neo-manager-installer--plugin-slug");
    dropdownNode.addEventListener("change", async () => {
        const switchNode = document.querySelector(`neo-switch-neo-draw-full.neo-manager-installer--plugin-active-switch[data-neo-manager-installer--plugin-slug="${pluginSlug}"]`);
        if (switchNode.loading) { return; }
        const switchNodeCheckedBefore = switchNode.checked;
        if (!switchNode.checked) { switchNode.checked = true; }
        switchNode.loading = true;
        document.title = "🔄 " + document.title;
        try {
            await activateOrDeactivatePlugin(true, pluginSlug, true);
            document.title = "✅ " + document.title;
            setTimeout(() => { document.title = document.title.replace("✅ ", ""); }, 5000);
        } catch (err) {
            switchNode.checked = switchNodeCheckedBefore;
            if (err.message === "abort") { return; }
            document.title = "❌ " + document.title;
            setTimeout(() => { document.title = document.title.replace("❌ ", ""); }, 5000);
            throw err;
        }
        finally { switchNode.loading = false; document.title = document.title.replace("🔄 ", ""); }
    });
});
