import React, {
  createContext,
  useCallback,
  useContext,
  useMemo,
  useState
} from "react";
import { useFetchSitePages } from "./site-pages-fetch-context/use-fetch-site-pages.js";
import { sitePagesPageType } from "./types.js";
const expireTime = 6e4;
const pagingLimit = 100;
const getCacheId = (pageType, query, itemPagePrefix) => itemPagePrefix ? itemPagePrefix : `${pageType} ${query.trim()}`.trim();
const SitePagesFetchContext = createContext({
  cache: {},
  expireCache: () => {
  },
  initialFetch: () => {
  },
  loadMore: () => {
  },
  preload: () => {
  },
  sitePublished: null
});
const SitePagesFetchContextProvider = ({ children }) => {
  const fetchSitePages = useFetchSitePages();
  const [cache, setCache] = useState({});
  const [expireTimeout, setExpireTimeout] = useState(void 0);
  const [sitePublished, setSitePublished] = useState(null);
  const expireCache = useCallback(() => {
    setExpireTimeout((oldTimeout) => {
      clearTimeout(oldTimeout);
      return setTimeout(() => setCache({}), expireTime);
    });
  }, []);
  const updateState = useCallback(
    (pageType, query, fn, itemPagePrefix) => {
      setCache((cache2) => {
        const cacheId = getCacheId(pageType, query, itemPagePrefix);
        const oldState = cache2[cacheId];
        const newState = fn(oldState);
        return newState && newState !== oldState ? { ...cache2, [cacheId]: newState } : cache2;
      });
    },
    []
  );
  const initialFetch = useCallback(
    (pageType, query, itemPagePrefix) => {
      const initialState = { type: "loading" };
      clearTimeout(expireTimeout);
      queueMicrotask(
        () => updateState(
          pageType,
          query,
          (oldState) => {
            if (oldState) {
              return;
            }
            fetchSitePages(pageType, {
              query: query.trim(),
              itemPagePrefix,
              paging: { limit: pagingLimit }
            }).then((result) => {
              updateState(
                pageType,
                query,
                (oldState2) => oldState2 === initialState && {
                  type: "ready",
                  items: result.items,
                  cursor: result.paging?.cursors?.next
                },
                itemPagePrefix
              );
              setSitePublished(
                (sitePublished2) => "published" in result ? result.published : sitePublished2
              );
            }).catch(
              (error) => updateState(
                pageType,
                query,
                (oldState2) => oldState2 === initialState && {
                  type: "loading-error",
                  error
                }
              )
            );
            return initialState;
          },
          itemPagePrefix
        )
      );
      return initialState;
    },
    [fetchSitePages, updateState]
  );
  const loadMore = useCallback(
    (pageType, query, itemPagePrefix) => {
      clearTimeout(expireTimeout);
      updateState(
        pageType,
        query,
        (oldState) => {
          if (!oldState || oldState.type !== "ready" || !oldState.cursor) {
            return;
          }
          const loadingState = {
            type: "loading-more",
            items: oldState.items,
            cursor: oldState.cursor
          };
          fetchSitePages(pageType, {
            query: query.trim(),
            itemPagePrefix,
            paging: { limit: pagingLimit, cursor: oldState.cursor }
          }).then((result) => {
            updateState(
              pageType,
              query,
              (oldState2) => oldState2 === loadingState && {
                type: "ready",
                items: [...oldState2.items, ...result.items],
                cursor: result.paging.cursors?.next
              },
              itemPagePrefix
            );
            setSitePublished(
              (sitePublished2) => "published" in result ? result.published : sitePublished2
            );
          }).catch(
            (error) => updateState(
              pageType,
              query,
              (oldState2) => oldState2 === loadingState && {
                type: "ready",
                error,
                cursor: oldState2.cursor,
                items: oldState2.items
              }
            )
          );
          return loadingState;
        },
        itemPagePrefix
      );
    },
    [fetchSitePages, updateState]
  );
  const preload = useCallback(() => {
    setExpireTimeout((oldTimeout) => {
      clearTimeout(oldTimeout);
      return void 0;
    });
    for (const pageType of Object.values(sitePagesPageType)) {
      initialFetch(pageType, "");
    }
  }, [initialFetch]);
  const value = useMemo(
    () => ({
      cache,
      expireCache,
      initialFetch,
      loadMore,
      preload,
      sitePublished
    }),
    [cache, expireCache, initialFetch, loadMore, preload, sitePublished]
  );
  return /* @__PURE__ */ React.createElement(SitePagesFetchContext.Provider, { children, value });
};
const useSitePagesFetchContext = (pageType, query, itemPagePrefix) => {
  const value = useContext(SitePagesFetchContext);
  const cacheId = getCacheId(pageType, query, itemPagePrefix);
  const fetchState = value.cache[cacheId] || value.initialFetch(pageType, query, itemPagePrefix);
  const loadMore = useMemo(
    () => fetchState && fetchState.type === "ready" && fetchState.cursor ? () => value.loadMore(pageType, query, itemPagePrefix) : void 0,
    [fetchState, value.loadMore]
  );
  return { fetchState, loadMore };
};
export {
  SitePagesFetchContext,
  SitePagesFetchContextProvider,
  useSitePagesFetchContext
};
//# sourceMappingURL=site-pages-fetch-context.js.map
