function runUploadAction(action) {
    const actions = {
        browse: () => el.fileInput?.click(),
        "start-upload": () => startUpload(),
        "copy-link": () => copyText("Share URL", shareUrl, shareUrl),
        clear: () => confirmClearQueue(),
        "toggle-delete-once": () => {
            if (!el.expiry?.querySelector(`option[value="${oneTimeRetentionKey}"]`)) return;
            el.expiry.value = isOneTimeDownloadSelected() ? defaultRetention : oneTimeRetentionKey;
            syncZipForRetention();
            saveSettings();
            syncMenuChecks();
            updateTerminal();
        },
        "random-password": () => randomPassword(),
        "random-box-name": () => randomBoxName(),
        "clear-password": () => {
            if (!el.password || uploadLocked) return;
            el.password.value = "";
            saveSettings();
            updateTerminal();
        },
        "toggle-page": () => {
            if (!el.downloadPage || uploadLocked) return;
            el.downloadPage.checked = !el.downloadPage.checked;
            saveSettings();
            syncMenuChecks();
        },
        help: () => openDoc("faq"),
        "side-help": () => {
            openDoc("faq");
            showToast("Terminal help opened. Copy the command and feed it files.");
        },
        "coming-soon": () => showToast("Coming Soon, not implemented just yet."),
        "fake-close": () => showToast("Close button denied. The upload window is staying open.", "warning"),
        minimize: () => showToast("Minimize requested. WarpBox stays visible so your queue is safe."),
        "toggle-fit": () => {
            document.body.classList.toggle("fit-window");
            showToast("Maximize requested. The pixel rectangle feels important now.");
        },
        "side-close": () => showToast("Box Options refuses to leave. Settings stay visible."),
        "side-folder-close": () => showToast("The folder window saw that click and chose denial."),
    };

    actions[action]?.();
}

document.addEventListener("click", (event) => {
    if (announceDisabledReason(event)) return;

    const menuButton = event.target.closest(".menu-button");
    if (menuButton) {
        const item = menuButton.closest(".menu-item");
        const isOpen = item.classList.contains("is-open");
        closeMenus();
        item.classList.toggle("is-open", !isOpen);
        menuButton.setAttribute("aria-expanded", String(!isOpen));
        return;
    }

    const action = event.target.closest("[data-action]")?.dataset.action;
    if (action) {
        closeMenus();
        runUploadAction(action);
        return;
    }

    const doc = event.target.closest("[data-doc]")?.dataset.doc;
    if (doc) {
        openDoc(doc);
        return;
    }

    const remove = event.target.closest("[data-remove]");
    if (remove) {
        removeFile(Number(remove.dataset.remove));
        return;
    }

    if (event.target.id === "duplicate-append") appendPendingDuplicates();
    if (event.target.id === "duplicate-skip") {
        pendingDuplicateFiles = [];
        closeDoc();
        showToast("Duplicate files skipped.");
    }
    if (event.target.id === "confirm-clear-yes") {
        closeDoc();
        clearQueue();
    }
    if (event.target.id === "confirm-clear-no" || event.target.id === "fallback-close") closeDoc();

    if (!event.target.closest(".menu-item")) {
        closeMenus();
    }
});

document.addEventListener("mousedown", (event) => {
    announceDisabledReason(event);
}, true);

document.querySelectorAll(".menu-item").forEach((item) => {
    item.addEventListener("mouseenter", () => {
        if (!document.querySelector(".menu-item.is-open")) return;
        closeMenus();
        item.classList.add("is-open");
        item.querySelector(".menu-button")?.setAttribute("aria-expanded", "true");
    });
});

el.fileInput?.addEventListener("change", () => addFiles(el.fileInput.files));

[el.dropSurface, el.dropzone].filter(Boolean).forEach((target) => {
    target.addEventListener("dragover", (event) => {
        event.preventDefault();
        el.dropzone?.classList.add("is-dragging");
    });
    target.addEventListener("dragleave", () => el.dropzone?.classList.remove("is-dragging"));
    target.addEventListener("drop", (event) => {
        event.preventDefault();
        el.dropzone?.classList.remove("is-dragging");
        addFiles(event.dataTransfer.files);
    });
});

el.dropzone?.addEventListener("keydown", (event) => {
    if (event.key === "Enter" || event.key === " ") {
        event.preventDefault();
        el.fileInput?.click();
    }
});

el.form?.addEventListener("submit", (event) => {
    event.preventDefault();
    startUpload();
});

el.copyButton?.addEventListener("click", () => copyText("Share URL", shareUrl, shareUrl));
el.copyCurlButton?.addEventListener("click", () => copyText("cURL command", getCurlCommand({ full: true })));
el.docPopupClose?.addEventListener("click", closeDoc);
el.modalBackdrop?.addEventListener("click", closeDoc);

el.maxViews?.addEventListener("wheel", (event) => {
    if (el.maxViews.disabled || el.maxViews.readOnly) return;
    event.preventDefault();
    const delta = event.deltaY < 0 ? 1 : -1;
    const modifier = event.ctrlKey && event.shiftKey ? 50 : event.shiftKey ? 15 : event.ctrlKey ? 5 : 1;
    const min = Number.parseInt(el.maxViews.min || "1", 10);
    const max = Number.parseInt(el.maxViews.max || "9999", 10);
    const current = Number.parseInt(el.maxViews.value || String(min), 10);
    el.maxViews.value = String(Math.max(min, Math.min(max, current + (delta * modifier))));
    saveSettings();
    updateTerminal();
});

el.apiKeyInput?.addEventListener("keydown", (event) => {
    const allowed = event.ctrlKey || event.metaKey || event.altKey || [
        "Tab",
        "Shift",
        "Control",
        "Alt",
        "Meta",
        "Escape",
        "ArrowLeft",
        "ArrowRight",
        "ArrowUp",
        "ArrowDown",
        "Home",
        "End",
        "PageUp",
        "PageDown",
    ].includes(event.key);
    if (allowed) return;
    event.preventDefault();
    showToast("Only pasting the API key is supported.", "warning");
    setStatus("Only pasting the API key is supported");
});

el.apiKeyInput?.addEventListener("paste", () => {
    setTimeout(validateApiKeyField, 0);
});

[el.expiry, el.password, el.maxViews, el.boxName, el.customSlug, el.downloadPage, el.allowZip, el.allowPreview, el.keepFilenames, el.privateBox, el.apiKeyMode, el.apiKeyInput].filter(Boolean).forEach((control) => {
    control.addEventListener("input", () => {
        if (control === el.boxName) syncSlugFromName();
        if (control === el.customSlug) {
            const clean = sanitizeSlugInput(el.customSlug.value);
            if (el.customSlug.value !== clean) el.customSlug.value = clean;
            el.customSlug.dataset.auto = "false";
        }
        if (control === el.apiKeyInput) validateApiKeyField();
        saveSettings();
        updateTerminal();
    });
    control.addEventListener("change", () => {
        if (control === el.expiry) syncZipForRetention();
        if (control === el.apiKeyMode) syncApiKeyField();
        saveSettings();
        syncMenuChecks();
        updateTerminal();
    });
});

document.addEventListener("keydown", (event) => {
    if (event.key === "Escape") {
        closeDoc();
        closeMenus();
    }
    if (event.key === "F1") {
        event.preventDefault();
        openDoc("faq");
    }
    if (event.ctrlKey && !event.shiftKey && !event.altKey) {
        const key = event.key.toLowerCase();
        if (key === "o") {
            event.preventDefault();
            el.fileInput?.click();
        }
        if (key === "u") {
            event.preventDefault();
            startUpload();
        }
        if (key === "k") {
            event.preventDefault();
            copyText("cURL command", getCurlCommand({ full: true }));
        }
        if (key === "l") {
            event.preventDefault();
            copyText("Share URL", shareUrl, shareUrl);
        }
    }
});

window.addEventListener("beforeunload", () => {
    files.forEach((item) => {
        if (item.previewURL) URL.revokeObjectURL(item.previewURL);
    });
});
