/*
 * URL state for dashboard variables.
 *
 * Selected values are reflected in the URL as `?var-<name>=<value>` so a
 * dashboard link is shareable with a specific scope already applied. We
 * use the *name* (not the id) because names are user-facing — links
 * survive across dashboards if a variable named `cluster` exists in both.
 *
 * Multi-select uses a `,` separator. Variable names are restricted to
 * `[A-Za-z_][A-Za-z0-9_]*` by the editor, which never collides with `,`.
 */
const VAR_PREFIX = "var-";
export default class DashboardVariableUrlState {
    static parseFromSearch(search) {
        const out = {};
        if (!search) {
            return out;
        }
        const params = new URLSearchParams(search.startsWith("?") ? search.slice(1) : search);
        params.forEach((rawValue, rawKey) => {
            if (!rawKey.startsWith(VAR_PREFIX)) {
                return;
            }
            const name = rawKey.slice(VAR_PREFIX.length);
            if (!name) {
                return;
            }
            const decoded = rawValue;
            if (decoded.includes(",")) {
                out[name] = {
                    selectedValues: decoded
                        .split(",")
                        .map((v) => {
                        return v.trim();
                    })
                        .filter((v) => {
                        return v.length > 0;
                    }),
                };
            }
            else {
                out[name] = { selectedValue: decoded };
            }
        });
        return out;
    }
    static applyUrlToVariables(variables, fromUrl) {
        return variables.map((variable) => {
            const fromName = fromUrl[variable.name];
            if (!fromName) {
                return variable;
            }
            return Object.assign(Object.assign({}, variable), { selectedValue: fromName.selectedValue, selectedValues: fromName.selectedValues });
        });
    }
    /*
     * Write the current variable selection to window.location without
     * pushing a history entry. We mutate only the `var-<name>` params so
     * unrelated query string state (auth tokens, filter overrides) is
     * preserved.
     *
     * No-op outside browser contexts so callers can be reused in SSR/tests.
     */
    static writeToBrowserUrl(variables) {
        if (typeof window === "undefined" ||
            typeof window.history === "undefined" ||
            typeof window.location === "undefined") {
            return;
        }
        const url = new URL(window.location.href);
        const params = url.searchParams;
        // Strip any prior var-* params so deleted variables stop appearing.
        const toDelete = [];
        params.forEach((_value, key) => {
            if (key.startsWith(VAR_PREFIX)) {
                toDelete.push(key);
            }
        });
        for (const key of toDelete) {
            params.delete(key);
        }
        for (const variable of variables) {
            const name = (variable.name || "").trim();
            if (!name) {
                continue;
            }
            const paramKey = `${VAR_PREFIX}${name}`;
            if (variable.selectedValues && variable.selectedValues.length > 0) {
                params.set(paramKey, variable.selectedValues.join(","));
                continue;
            }
            if (variable.selectedValue && variable.selectedValue.length > 0) {
                params.set(paramKey, variable.selectedValue);
            }
        }
        const nextSearch = params.toString();
        const nextUrl = `${url.pathname}${nextSearch ? `?${nextSearch}` : ""}${url.hash || ""}`;
        window.history.replaceState(window.history.state, "", nextUrl);
    }
}
//# sourceMappingURL=VariableUrlState.js.map