import "setimmediate";
import { StoreProvider } from "easy-peasy";
import NextApp, { AppContext } from "next/app";
import React, { useMemo } from "react";
import { QueryClientProvider } from "react-query";

import {
  ApiPrefetch,
  setPreviewToken,
  useImmediateEffect,
  getQueryClient,
} from "mazlo-api";
import { useRouter, RouterProvider } from "mazlo-ui";

import { getOrCreateStore } from "../../services/store";
import { AlertProvider } from "../Alert";
import { View } from "../View";
import { AppProps } from "./";

const App = ({ Component, initialStore, pageProps, prefetch }: AppProps) => {
  const store = useMemo(
    () => getOrCreateStore(initialStore || pageProps?.initialStore || {}),
    [initialStore, pageProps?.initialStore]
  );
  const { query } = useRouter();
  useImmediateEffect(() => {
    setPreviewToken(query?.previewToken ? `${query?.previewToken}` : null);
    if (typeof window !== "undefined") {
      ApiPrefetch.hydrate(prefetch);
    }
  }, [query]);

  return (
    <RouterProvider>
      <QueryClientProvider client={getQueryClient()}>
        <StoreProvider store={store}>
          <Component {...pageProps} />
          <View
            nativeID="portal"
            style={{ position: "absolute", top: 0, left: 0, zIndex: 10000 }}
          />
          <AlertProvider />
        </StoreProvider>
      </QueryClientProvider>
    </RouterProvider>
  );
};

export default App;

export const getInitialProps = async (appContext: AppContext) => {
  ApiPrefetch.reset();

  const appProps = await NextApp.getInitialProps(appContext);

  return {
    ...appProps,
    prefetch: ApiPrefetch.getAll(),
  };
};
