var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { addClass, removeClass } from "@matdata/yasgui-utils";
import { getWorkspaceBackend } from "./backends/getWorkspaceBackend";
import { normalizeQueryFilename } from "./normalizeQueryFilename";
import "./SaveManagedQueryModal.scss";
export default class SaveManagedQueryModal {
    constructor(yasgui) {
        this.saveBtnOriginalText = "Save";
        this.filenameTouched = false;
        this.folderPickerOpen = false;
        this.folderBrowsePath = "";
        this.yasgui = yasgui;
        this.overlayEl = document.createElement("div");
        addClass(this.overlayEl, "saveManagedQueryModalOverlay");
        this.modalEl = document.createElement("div");
        addClass(this.modalEl, "saveManagedQueryModal");
        this.modalEl.addEventListener("click", (e) => e.stopPropagation());
        const headerEl = document.createElement("div");
        addClass(headerEl, "saveManagedQueryModalHeader");
        const titleEl = document.createElement("h2");
        titleEl.textContent = "Save as managed query";
        const closeBtn = document.createElement("button");
        closeBtn.type = "button";
        closeBtn.className = "closeButton";
        closeBtn.setAttribute("aria-label", "Close");
        closeBtn.innerHTML = "&times;";
        closeBtn.addEventListener("click", () => this.cancel());
        headerEl.appendChild(titleEl);
        headerEl.appendChild(closeBtn);
        this.formEl = document.createElement("form");
        this.formEl.addEventListener("submit", (e) => {
            e.preventDefault();
            this.submit();
        });
        const bodyEl = document.createElement("div");
        addClass(bodyEl, "saveManagedQueryModalBody");
        this.workspaceSelectEl = document.createElement("select");
        this.workspaceSelectEl.setAttribute("aria-label", "Workspace");
        this.workspaceSelectEl.addEventListener("change", () => {
            this.applyWorkspaceTypeUI();
            if (!this.folderPickerOpen)
                return;
            this.folderBrowsePath = "";
            this.folderPathEl.value = "";
            void this.refreshFolderPicker();
        });
        this.folderPathEl = document.createElement("input");
        this.folderPathEl.type = "text";
        this.folderPathEl.placeholder = "Select a folder (optional)";
        this.folderPathEl.setAttribute("aria-label", "Folder path");
        this.folderPathEl.readOnly = true;
        this.folderPickerToggleEl = document.createElement("button");
        this.folderPickerToggleEl.type = "button";
        this.folderPickerToggleEl.textContent = "Choose…";
        addClass(this.folderPickerToggleEl, "folderPickerToggle");
        this.folderPickerToggleEl.addEventListener("click", () => {
            this.folderPickerOpen = !this.folderPickerOpen;
            if (this.folderPickerOpen) {
                addClass(this.folderPickerEl, "open");
                this.folderBrowsePath = this.folderPathEl.value.trim();
                void this.refreshFolderPicker();
            }
            else {
                removeClass(this.folderPickerEl, "open");
            }
        });
        this.folderPickerEl = document.createElement("div");
        addClass(this.folderPickerEl, "folderPicker");
        this.folderPickerPathEl = document.createElement("div");
        addClass(this.folderPickerPathEl, "folderPickerPath");
        this.folderPickerErrorEl = document.createElement("div");
        addClass(this.folderPickerErrorEl, "folderPickerError");
        this.folderPickerListEl = document.createElement("div");
        addClass(this.folderPickerListEl, "folderPickerList");
        const folderPickerActionsEl = document.createElement("div");
        addClass(folderPickerActionsEl, "folderPickerActions");
        const upBtn = document.createElement("button");
        upBtn.type = "button";
        upBtn.textContent = "Up";
        upBtn.addEventListener("click", () => {
            const parts = this.folderBrowsePath.split("/").filter(Boolean);
            parts.pop();
            this.folderBrowsePath = parts.join("/");
            this.folderPathEl.value = this.folderBrowsePath;
            void this.refreshFolderPicker();
        });
        const rootBtn = document.createElement("button");
        rootBtn.type = "button";
        rootBtn.textContent = "Root";
        rootBtn.addEventListener("click", () => {
            this.folderBrowsePath = "";
            this.folderPathEl.value = "";
            void this.refreshFolderPicker();
        });
        folderPickerActionsEl.appendChild(rootBtn);
        folderPickerActionsEl.appendChild(upBtn);
        const newFolderRowEl = document.createElement("div");
        addClass(newFolderRowEl, "newFolderRow");
        this.newFolderNameEl = document.createElement("input");
        this.newFolderNameEl.type = "text";
        this.newFolderNameEl.placeholder = "New folder name";
        this.newFolderNameEl.setAttribute("aria-label", "New folder name");
        this.newFolderNameEl.addEventListener("keydown", (e) => {
            if (e.key === "Enter") {
                e.preventDefault();
                e.stopPropagation();
                this.createNewFolderSelection();
            }
        });
        const createFolderBtn = document.createElement("button");
        createFolderBtn.type = "button";
        createFolderBtn.textContent = "Create";
        createFolderBtn.addEventListener("click", () => this.createNewFolderSelection());
        newFolderRowEl.appendChild(this.newFolderNameEl);
        newFolderRowEl.appendChild(createFolderBtn);
        this.folderPickerEl.appendChild(this.folderPickerPathEl);
        this.folderPickerEl.appendChild(folderPickerActionsEl);
        this.folderPickerEl.appendChild(this.folderPickerErrorEl);
        this.folderPickerEl.appendChild(this.folderPickerListEl);
        this.folderPickerEl.appendChild(newFolderRowEl);
        this.nameEl = document.createElement("input");
        this.nameEl.type = "text";
        this.nameEl.placeholder = "Name";
        this.nameEl.setAttribute("aria-label", "Name");
        this.nameEl.addEventListener("input", () => {
            if (this.filenameTouched)
                return;
            const suggested = this.suggestFilenameFromName(this.nameEl.value);
            if (suggested)
                this.filenameEl.value = suggested.replace(/\.sparql$/i, "");
        });
        this.filenameEl = document.createElement("input");
        this.filenameEl.type = "text";
        this.filenameEl.placeholder = "Filename (e.g., my-query)";
        this.filenameEl.setAttribute("aria-label", "Filename");
        this.filenameEl.addEventListener("input", () => {
            this.filenameTouched = true;
        });
        this.messageEl = document.createElement("input");
        this.messageEl.type = "text";
        this.messageEl.placeholder = "Save message (optional)";
        this.messageEl.setAttribute("aria-label", "Save message");
        const workspaceRow = this.row("Workspace", this.workspaceSelectEl);
        const folderRow = this.folderRow();
        this.nameRowEl = this.row("Name", this.nameEl);
        this.filenameRowEl = this.row("Filename", this.filenameEl);
        this.messageRowEl = document.createElement("div");
        addClass(this.messageRowEl, "saveManagedQueryModalRow");
        this.messageLabelEl = document.createElement("label");
        this.messageLabelEl.textContent = "Message";
        this.messageRowEl.appendChild(this.messageLabelEl);
        this.messageRowEl.appendChild(this.messageEl);
        bodyEl.appendChild(workspaceRow);
        bodyEl.appendChild(folderRow);
        bodyEl.appendChild(this.folderPickerEl);
        bodyEl.appendChild(this.nameRowEl);
        bodyEl.appendChild(this.filenameRowEl);
        bodyEl.appendChild(this.messageRowEl);
        const footerEl = document.createElement("div");
        addClass(footerEl, "saveManagedQueryModalFooter");
        this.cancelBtn = document.createElement("button");
        this.cancelBtn.type = "button";
        this.cancelBtn.textContent = "Cancel";
        this.cancelBtn.addEventListener("click", () => this.cancel());
        this.saveBtn = document.createElement("button");
        this.saveBtn.type = "submit";
        this.saveBtn.textContent = "Save";
        this.saveBtnOriginalText = "Save";
        addClass(this.saveBtn, "primary");
        footerEl.appendChild(this.cancelBtn);
        footerEl.appendChild(this.saveBtn);
        this.formEl.appendChild(bodyEl);
        this.formEl.appendChild(footerEl);
        this.modalEl.appendChild(headerEl);
        this.modalEl.appendChild(this.formEl);
        this.overlayEl.appendChild(this.modalEl);
        this.overlayEl.addEventListener("click", () => this.cancel());
        document.addEventListener("keydown", (e) => {
            if (!this.isOpen())
                return;
            if (e.key === "Escape") {
                e.preventDefault();
                this.cancel();
            }
        });
        this.close();
    }
    applyWorkspaceTypeUI() {
        const workspace = this.getSelectedWorkspace();
        const isGit = (workspace === null || workspace === void 0 ? void 0 : workspace.type) === "git";
        const isSparql = (workspace === null || workspace === void 0 ? void 0 : workspace.type) === "sparql";
        this.nameRowEl.style.display = isGit ? "none" : "";
        this.filenameRowEl.style.display = isSparql ? "none" : "";
        this.messageRowEl.style.display = isGit ? "none" : "";
        if (isSparql) {
            this.messageLabelEl.textContent = "Description";
            this.messageEl.placeholder = "Description (optional)";
            this.messageEl.setAttribute("aria-label", "Description");
        }
        else {
            this.messageLabelEl.textContent = "Message";
            this.messageEl.placeholder = "Save message (optional)";
            this.messageEl.setAttribute("aria-label", "Save message");
        }
    }
    folderRow() {
        const rowEl = document.createElement("div");
        addClass(rowEl, "saveManagedQueryModalRow");
        const labelEl = document.createElement("label");
        labelEl.textContent = "Folder";
        const containerEl = document.createElement("div");
        addClass(containerEl, "folderPathContainer");
        containerEl.appendChild(this.folderPathEl);
        containerEl.appendChild(this.folderPickerToggleEl);
        rowEl.appendChild(labelEl);
        rowEl.appendChild(containerEl);
        return rowEl;
    }
    row(label, inputEl) {
        const rowEl = document.createElement("div");
        addClass(rowEl, "saveManagedQueryModalRow");
        const labelEl = document.createElement("label");
        labelEl.textContent = label;
        rowEl.appendChild(labelEl);
        rowEl.appendChild(inputEl);
        return rowEl;
    }
    isOpen() {
        return this.overlayEl.classList.contains("open");
    }
    open() {
        addClass(this.overlayEl, "open");
    }
    close() {
        removeClass(this.overlayEl, "open");
    }
    cancel() {
        var _a;
        this.close();
        this.overlayEl.remove();
        (_a = this.reject) === null || _a === void 0 ? void 0 : _a.call(this, new Error("cancelled"));
        this.resolve = undefined;
        this.reject = undefined;
    }
    setLoading(isLoading) {
        if (isLoading) {
            this.saveBtn.disabled = true;
            this.cancelBtn.disabled = true;
            this.saveBtn.textContent = "Saving…";
            addClass(this.saveBtn, "saving");
        }
        else {
            this.saveBtn.disabled = false;
            this.cancelBtn.disabled = false;
            this.saveBtn.textContent = this.saveBtnOriginalText;
            removeClass(this.saveBtn, "saving");
        }
    }
    notifySaveInProgress() {
        this.setLoading(true);
    }
    notifySaveComplete() {
        this.setLoading(false);
    }
    submit() {
        var _a;
        const workspaceId = this.workspaceSelectEl.value;
        const name = this.nameEl.value.trim();
        const filename = this.filenameEl.value.trim();
        const folderPath = this.folderPathEl.value.trim();
        const message = this.messageEl.value.trim();
        const workspace = this.getSelectedWorkspace();
        const isGit = (workspace === null || workspace === void 0 ? void 0 : workspace.type) === "git";
        const isSparql = (workspace === null || workspace === void 0 ? void 0 : workspace.type) === "sparql";
        if (!workspaceId) {
            window.alert("Please select a workspace");
            return;
        }
        let resolvedName = name;
        let resolvedFilename = filename;
        if (isGit) {
            resolvedFilename = resolvedFilename.replace(/\.sparql$/i, "");
            if (!resolvedFilename) {
                window.alert("Please enter a filename");
                return;
            }
            const base = resolvedFilename.replace(/^.*\//, "");
            resolvedName = base || resolvedFilename;
        }
        else if (isSparql) {
            if (!resolvedName) {
                window.alert("Please enter a name");
                return;
            }
            resolvedFilename = this.suggestFilenameFromName(resolvedName) || normalizeQueryFilename(resolvedName);
        }
        else {
            if (!resolvedFilename) {
                window.alert("Please enter a filename");
                return;
            }
            if (!resolvedName) {
                window.alert("Please enter a name");
                return;
            }
        }
        this.close();
        this.overlayEl.remove();
        (_a = this.resolve) === null || _a === void 0 ? void 0 : _a.call(this, {
            workspaceId,
            folderPath,
            name: resolvedName,
            filename: resolvedFilename,
            message: isGit ? undefined : message || undefined,
        });
        this.resolve = undefined;
        this.reject = undefined;
    }
    show(defaults) {
        return __awaiter(this, void 0, void 0, function* () {
            var _a, _b, _c, _d, _e, _f, _g;
            const workspaces = this.yasgui.persistentConfig.getWorkspaces();
            const activeWorkspaceId = this.yasgui.persistentConfig.getActiveWorkspaceId();
            const selectedWorkspaceId = (defaults === null || defaults === void 0 ? void 0 : defaults.workspaceId) || activeWorkspaceId || ((_b = (_a = workspaces[0]) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : "");
            const orderedWorkspaces = selectedWorkspaceId
                ? [
                    ...workspaces.filter((w) => w.id === selectedWorkspaceId),
                    ...workspaces.filter((w) => w.id !== selectedWorkspaceId),
                ]
                : workspaces;
            this.workspaceSelectEl.innerHTML = "";
            for (const w of orderedWorkspaces) {
                const opt = document.createElement("option");
                opt.value = w.id;
                opt.textContent = w.label;
                this.workspaceSelectEl.appendChild(opt);
            }
            this.workspaceSelectEl.value = selectedWorkspaceId;
            this.applyWorkspaceTypeUI();
            this.folderPathEl.value = (_c = defaults === null || defaults === void 0 ? void 0 : defaults.folderPath) !== null && _c !== void 0 ? _c : "";
            this.filenameTouched = false;
            const defaultName = (_d = defaults === null || defaults === void 0 ? void 0 : defaults.name) !== null && _d !== void 0 ? _d : "";
            this.nameEl.value = defaultName;
            const defaultFilename = (_e = defaults === null || defaults === void 0 ? void 0 : defaults.filename) !== null && _e !== void 0 ? _e : (defaultName ? ((_f = this.suggestFilenameFromName(defaultName)) !== null && _f !== void 0 ? _f : "") : "");
            this.filenameEl.value = defaultFilename.replace(/\.sparql$/i, "");
            this.messageEl.value = (_g = defaults === null || defaults === void 0 ? void 0 : defaults.message) !== null && _g !== void 0 ? _g : "";
            this.folderPickerOpen = false;
            removeClass(this.folderPickerEl, "open");
            this.folderBrowsePath = this.folderPathEl.value.trim();
            this.folderPickerErrorEl.textContent = "";
            this.folderPickerListEl.innerHTML = "";
            document.body.appendChild(this.overlayEl);
            this.open();
            const selected = this.getSelectedWorkspace();
            if ((selected === null || selected === void 0 ? void 0 : selected.type) === "git") {
                this.filenameEl.focus();
            }
            else {
                this.nameEl.focus();
            }
            return yield new Promise((resolve, reject) => {
                this.resolve = resolve;
                this.reject = reject;
            });
        });
    }
    suggestFilenameFromName(name) {
        const trimmed = name.trim();
        if (!trimmed)
            return undefined;
        const safe = trimmed.replace(/[\\/]/g, "-");
        try {
            return normalizeQueryFilename(safe);
        }
        catch (_a) {
            return undefined;
        }
    }
    getSelectedWorkspace() {
        const workspaceId = this.workspaceSelectEl.value;
        return this.yasgui.persistentConfig.getWorkspace(workspaceId);
    }
    refreshFolderPicker() {
        return __awaiter(this, void 0, void 0, function* () {
            this.folderPickerErrorEl.textContent = "";
            this.folderPickerListEl.innerHTML = "";
            this.folderPickerPathEl.textContent = this.folderBrowsePath
                ? `Current: ${this.folderBrowsePath}`
                : "Current: (root)";
            const workspace = this.getSelectedWorkspace();
            if (!workspace) {
                this.folderPickerErrorEl.textContent = "Workspace not found";
                return;
            }
            const backend = getWorkspaceBackend(workspace, { persistentConfig: this.yasgui.persistentConfig });
            let entries = [];
            try {
                entries = yield backend.listFolder(this.folderBrowsePath || undefined);
            }
            catch (e) {
                const err = e;
                if ((err === null || err === void 0 ? void 0 : err.code) && err.code !== "NOT_FOUND") {
                    this.folderPickerErrorEl.textContent = err.message || String(e);
                    return;
                }
                entries = [];
            }
            const folders = entries
                .filter((x) => x.kind === "folder")
                .sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: "base" }));
            if (folders.length === 0) {
                const emptyEl = document.createElement("div");
                addClass(emptyEl, "folderPickerEmpty");
                emptyEl.textContent = "No subfolders";
                this.folderPickerListEl.appendChild(emptyEl);
                return;
            }
            for (const f of folders) {
                const btn = document.createElement("button");
                btn.type = "button";
                addClass(btn, "folderPickerItem");
                btn.textContent = f.label;
                btn.addEventListener("click", () => {
                    this.folderBrowsePath = f.id;
                    this.folderPathEl.value = f.id;
                    void this.refreshFolderPicker();
                });
                this.folderPickerListEl.appendChild(btn);
            }
        });
    }
    createNewFolderSelection() {
        const name = this.newFolderNameEl.value.trim();
        if (!name)
            return;
        const safe = name.replace(/[\\/]/g, "-");
        this.folderBrowsePath = this.folderBrowsePath ? `${this.folderBrowsePath}/${safe}` : safe;
        this.folderPathEl.value = this.folderBrowsePath;
        this.newFolderNameEl.value = "";
        void this.refreshFolderPicker();
    }
}
//# sourceMappingURL=SaveManagedQueryModal.js.map