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

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

import "../styles/globals.scss";
import { pageview } from "../libs/gtag";
import { GA_TRACKING_ID } from "../libs/config";
import { get } from "../utils/http";
import Head from "next/head";

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;
  const router = useRouter();

  useEffect(() => {
    const handleRouteChange = (url: string) => {
      pageview(url);
    };
    router.events.on("routeChangeComplete", handleRouteChange);
    router.events.on("hashChangeComplete", handleRouteChange);
    return () => {
      router.events.off("routeChangeComplete", handleRouteChange);
      router.events.off("hashChangeComplete", handleRouteChange);
    };
  }, [router.events]);

  return (
    <>
      <Head>
        <meta charSet="utf-8" />
        <meta httpEquiv="X-UA-Compatible" content="IE=edge" />
        <meta
          name="viewport"
          content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"
        />
        <title>NovelDit - Read Novels Online for Free</title>
        <meta
          name="description"
          content="We are offering free books online read! Read novel updated daily: light novel translations, web novel, chinese novel, japanese novel, korean novel and other novel online."
        />
        <meta
          name="keywords"
          content="Novel updates, Free books online, Light Novel, Read light novel, Light novel translations, Free Novels Online"
        />
        <link rel="manifest" href="/manifest.json" />
        <link rel="icon" href="/logo.svg" type="image/svg+xml" />
        <link rel="icon" href="/favicon.ico" type="image/x-icon" />
        <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
        <link rel="mask-icon" href="/logo.svg" color="#000000" />
        <link
          href="/favicon-16x16.png"
          rel="icon"
          type="image/png"
          sizes="16x16"
        />
        <link
          href="/favicon-32x32.png"
          rel="icon"
          type="image/png"
          sizes="32x32"
        />
        <link rel="apple-touch-icon" href="/apple-touch-icon.png" />
        <meta name="theme-color" content="#111827" />
      </Head>
      <Script
        strategy="afterInteractive"
        src={`https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}`}
      />
      <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 get("/api/genre/list");

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

export default MyApp;
