import { isInDocument } from "../../../utils/utils.js";
const isRefineModalFacet = 'is-refine-modal';
function createAppLoadedListener(store, callback) {
    const updateIsAppLoaded = ()=>{
        const isAppLoaded = 0 === store.state.loadingFlags.length;
        callback(isAppLoaded);
    };
    store.onChange('loadingFlags', updateIsAppLoaded);
    updateIsAppLoaded();
}
function createBaseStore(initialState) {
    const store = createStore(initialState);
    return {
        ...store,
        getUniqueIDFromEngine (_engine) {
            throw new Error('getUniqueIDFromEngine not implemented at the base store level.');
        }
    };
}
function registerFacet(store, facetType, data) {
    const clearExistingFacetElement = (facetType, facetId)=>{
        if (store.state[facetType][facetId]) store.state.facetElements = store.state.facetElements.filter((facetElement)=>facetElement.getAttribute('facet-id') !== facetId);
    };
    if (null !== data.element.getAttribute(isRefineModalFacet)) return;
    clearExistingFacetElement(facetType, data.facetId);
    store.state.facetElements.push(data.element);
    store.state[facetType][data.facetId] = data;
}
function setLoadingFlag(store, loadingFlag) {
    const flags = store.state.loadingFlags;
    store.state.loadingFlags = flags.concat(loadingFlag);
}
function unsetLoadingFlag(store, loadingFlag) {
    const flags = store.state.loadingFlags;
    store.state.loadingFlags = flags.filter((value)=>value !== loadingFlag);
}
function getFacetElements(store) {
    return store.state.facetElements.filter((element)=>isInDocument(element));
}
function waitUntilAppLoaded(store, callback) {
    if (store.state.loadingFlags.length) store.onChange('loadingFlags', (flags)=>{
        if (!flags.length) callback();
    });
    else callback();
}
function createStore(initialState) {
    const listeners = new Map();
    const state = new Proxy(initialState, {
        set (target, prop, value) {
            const oldValue = target[prop];
            if (oldValue !== value) {
                target[prop] = value;
                if (listeners.has(prop)) for (const cb of listeners.get(prop))cb(value);
            }
            return true;
        }
    });
    const get = (propName)=>state[propName];
    const set = (propName, value)=>{
        state[propName] = value;
    };
    const onChange = (propName, callback)=>{
        if (!listeners.has(propName)) listeners.set(propName, new Set());
        listeners.get(propName).add(callback);
        return ()=>{
            listeners.get(propName).delete(callback);
            if (0 === listeners.get(propName).size) listeners.delete(propName);
        };
    };
    return {
        state,
        get,
        set,
        onChange
    };
}
export { createAppLoadedListener, createBaseStore, getFacetElements, isRefineModalFacet, registerFacet, setLoadingFlag, unsetLoadingFlag, waitUntilAppLoaded };
