import { SWRConfig } from "swr";
import type { NextPage } from "next";
import type { AppProps } from "next/app";
import App, { AppContext } from "next/app";
import type { ReactElement, ReactNode } from "react";

import { Context } from "../libs/context";
import Layout from "../components/common/Layout";

import "../styles/globals.scss";

export type NextPageWithLayout<P = {}, IP = P> = NextPage<P, IP> & {
  getLayout?: (page: ReactElement) => ReactNode;
};

type AppPropsWithLayout = AppProps & {
  Component: NextPageWithLayout;
  pageProps: {
    fallback?: {
      [key: string]: any;
    };
    [key: string]: any;
  };
};

const MyApp = ({ Component, pageProps }: AppPropsWithLayout) => {
  const { fallback, genre, ...otherProps } = pageProps;

  return (
    <Context.Provider value={{ genre }}>
      <SWRConfig value={{ fallback, revalidateIfStale: false }}>
        {Component.getLayout ? (
          Component.getLayout(<Component {...otherProps} />)
        ) : (
          <Layout>
            <Component {...otherProps} />
          </Layout>
        )}
      </SWRConfig>
    </Context.Provider>
  );
};

MyApp.getInitialProps = async function (context: AppContext) {
  App.getInitialProps(context);

  const { data } = await fetch("https://novels.yergoo.com/api/genre/list").then(
    (res) => res.json()
  );

  return {
    pageProps: { genre: data },
  };
};

export default MyApp;
