function safeParse(rawValue) {
    if (rawValue == null)
        return null;
    try {
        return JSON.parse(rawValue);
    }
    catch {
        return rawValue;
    }
}
function setOrDelete(urlParams, paramKey, paramValue) {
    if (paramValue === undefined || paramValue === null || paramValue === "") {
        urlParams.delete(paramKey);
    }
    else {
        urlParams.set(paramKey, typeof paramValue === "string" ? paramValue : JSON.stringify(paramValue));
    }
}
const ALL_QUERY_KEYS = [
    "search",
    "text",
    "textOnChange",
    "selection",
    "filters",
];
export function loadQueryString(defaultValue, queryStringMap) {
    const searchParams = new URLSearchParams(window.location.search);
    const mergedValueRecord = { ...defaultValue };
    if (queryStringMap) {
        const mappingKeys = Object.keys(queryStringMap).filter((k) => k !== "keyObj");
        if (queryStringMap.keyObj && searchParams.has(queryStringMap.keyObj)) {
            const mappedObject = safeParse(searchParams.get(queryStringMap.keyObj));
            if (mappedObject && typeof mappedObject === "object") {
                for (const key of mappingKeys) {
                    const mappedKey = queryStringMap[key];
                    if (Object.prototype.hasOwnProperty.call(mappedObject, mappedKey)) {
                        mergedValueRecord[key] = mappedObject[mappedKey];
                    }
                }
            }
        }
        else {
            for (const key of mappingKeys) {
                const mappedKey = queryStringMap[key];
                if (searchParams.has(mappedKey)) {
                    if (key === "filters") {
                        const parsedValue = safeParse(searchParams.get(mappedKey));
                        mergedValueRecord[key] = deserializeFiltersGrouped(parsedValue);
                    }
                    else {
                        mergedValueRecord[key] = safeParse(searchParams.get(mappedKey));
                    }
                }
            }
        }
    }
    else {
        const parsedQueryObject = safeParse(searchParams.get("q"));
        if (parsedQueryObject && typeof parsedQueryObject === "object") {
            Object.assign(mergedValueRecord, parsedQueryObject);
        }
        for (const key of ALL_QUERY_KEYS) {
            if (searchParams.has(key)) {
                if (key === "filters") {
                    const parsedValue = safeParse(searchParams.get(key));
                    mergedValueRecord[key] = deserializeFiltersGrouped(parsedValue);
                }
                else {
                    mergedValueRecord[key] = safeParse(searchParams.get(key));
                }
            }
        }
    }
    if (!mergedValueRecord["textOnChange"] && mergedValueRecord["text"]) {
        mergedValueRecord["textOnChange"] = mergedValueRecord["text"];
    }
    return mergedValueRecord;
}
export function saveQueryString(value, queryStringMap) {
    const searchParams = new URLSearchParams(window.location.search);
    if (queryStringMap) {
        const mappingKeys = Object.keys(queryStringMap).filter((k) => k !== "keyObj");
        const payloadObject = {};
        for (const key of mappingKeys) {
            const mappedKey = queryStringMap[key];
            let valueForKey = value[key];
            if (key === "filters") {
                valueForKey = serializeFiltersGrouped(valueForKey);
            }
            if (Array.isArray(valueForKey) && valueForKey.length === 0)
                continue;
            if (valueForKey !== undefined &&
                valueForKey !== null &&
                valueForKey !== "") {
                payloadObject[mappedKey] = valueForKey;
            }
        }
        if (queryStringMap.keyObj) {
            if (Object.keys(payloadObject).length > 0) {
                searchParams.set(queryStringMap.keyObj, JSON.stringify(payloadObject));
            }
            else {
                searchParams.delete(queryStringMap.keyObj);
            }
            for (const key of mappingKeys)
                searchParams.delete(queryStringMap[key]);
        }
        else {
            for (const key of mappingKeys) {
                let valueForKey = value[key];
                if (key === "filters") {
                    valueForKey = serializeFiltersGrouped(valueForKey);
                }
                if (Array.isArray(valueForKey) && valueForKey.length === 0) {
                    setOrDelete(searchParams, queryStringMap[key], undefined);
                }
                else {
                    setOrDelete(searchParams, queryStringMap[key], valueForKey);
                }
            }
        }
    }
    else {
        for (const key of ALL_QUERY_KEYS) {
            let valueForKey = value[key];
            if (key === "filters") {
                valueForKey =
                    Array.isArray(valueForKey) && valueForKey.length === 0
                        ? undefined
                        : serializeFiltersGrouped(valueForKey);
            }
            if (searchParams.has(key) || valueForKey !== undefined) {
                setOrDelete(searchParams, key, valueForKey);
            }
        }
    }
    const queryString = searchParams.toString();
    const nextUrl = queryString
        ? `${window.location.pathname}?${queryString}`
        : window.location.pathname;
    window.history.replaceState(null, "", nextUrl);
}
export function loadLocalStorage(defaultValue, storageKey, queryStringMap) {
    const rawStored = typeof window !== "undefined" && typeof window.localStorage !== "undefined"
        ? window.localStorage.getItem(storageKey)
        : null;
    const mergedValueRecord = { ...defaultValue };
    if (!rawStored) {
        if (mergedValueRecord["textOnChange"] == null &&
            mergedValueRecord["text"] != null) {
            mergedValueRecord["textOnChange"] = mergedValueRecord["text"];
        }
        return mergedValueRecord;
    }
    const parsedStoredData = safeParse(rawStored);
    if (!parsedStoredData || typeof parsedStoredData !== "object") {
        if (mergedValueRecord["textOnChange"] == null &&
            mergedValueRecord["text"] != null) {
            mergedValueRecord["textOnChange"] = mergedValueRecord["text"];
        }
        return mergedValueRecord;
    }
    if (queryStringMap) {
        const mappingKeys = Object.keys(queryStringMap).filter((k) => k !== "keyObj");
        for (const key of mappingKeys) {
            const mappedKey = queryStringMap[key];
            if (mappedKey &&
                Object.prototype.hasOwnProperty.call(parsedStoredData, mappedKey)) {
                mergedValueRecord[key] = parsedStoredData[mappedKey];
            }
        }
    }
    else {
        Object.assign(mergedValueRecord, parsedStoredData);
    }
    if (mergedValueRecord["textOnChange"] == null &&
        mergedValueRecord["text"] != null) {
        mergedValueRecord["textOnChange"] = mergedValueRecord["text"];
    }
    return mergedValueRecord;
}
export function saveLocalStorage(value, storageKey, queryStringMap) {
    let payloadObject = {};
    if (queryStringMap) {
        const mappingKeys = Object.keys(queryStringMap).filter((k) => k !== "keyObj");
        for (const key of mappingKeys) {
            const mappedKey = queryStringMap[key];
            const valueForKey = value[key];
            if (Array.isArray(valueForKey) && valueForKey.length === 0)
                continue;
            if (valueForKey !== undefined &&
                valueForKey !== null &&
                valueForKey !== "") {
                payloadObject[mappedKey] = valueForKey;
            }
        }
        if (queryStringMap.keyObj) {
            if (Object.keys(payloadObject).length > 0) {
                localStorage.setItem(storageKey, JSON.stringify(payloadObject));
            }
            else {
                localStorage.removeItem(storageKey);
            }
        }
        else {
            if (Object.keys(payloadObject).length > 0) {
                localStorage.setItem(storageKey, JSON.stringify(payloadObject));
            }
            else {
                localStorage.removeItem(storageKey);
            }
        }
    }
    else {
        if (value && Object.keys(value).length > 0) {
            localStorage.setItem(storageKey, JSON.stringify(value));
        }
        else {
            localStorage.removeItem(storageKey);
        }
    }
}
export function serializeFilters(filters) {
    return (filters || []).map((token) => ({
        value: token.values?.[0] ?? "",
        suggestionCategoryId: token.suggestionCategoryId,
        tokenType: token.tokenType,
        keywordKey: token.keywordKey,
    }));
}
export function deserializeFilters(serializedArray) {
    if (!Array.isArray(serializedArray))
        return [];
    return serializedArray.map((item) => ({
        values: [item.value],
        suggestionCategoryId: item.suggestionCategoryId,
        tokenType: item.tokenType,
        keywordKey: item.keywordKey,
        filter: true,
        isFilter: true,
    }));
}
export function serializeFiltersGrouped(filters) {
    if (!filters || filters.length === 0)
        return undefined;
    return {
        values: filters.map((token) => token.values?.[0] ?? ""),
        suggestionCategoryId: filters.map((token) => token.suggestionCategoryId),
        tokenType: filters.map((token) => token.tokenType),
        keywordKey: filters.map((token) => token.keywordKey),
    };
}
export function deserializeFiltersGrouped(serialized) {
    if (!serialized || !Array.isArray(serialized.values))
        return [];
    return serialized.values.map((valueItem, index) => ({
        values: [valueItem],
        suggestionCategoryId: serialized.suggestionCategoryId?.[index],
        tokenType: serialized.tokenType?.[index],
        keywordKey: serialized.keywordKey?.[index],
        filter: true,
        isFilter: true,
    }));
}
