import React, { useEffect, useState } from "react";

import type { GetStaticPropsContext } from "next";

import { useRouter } from "../services/Router";

export function withStaticProps(
  getStaticProps: (context: GetStaticPropsContext) => Promise<any>,
  ErrorComponent: React.ComponentType<{ statusCode?: number }>
) {
  return (Component: React.ComponentType<any>) => () => {
    const router = useRouter();
    const [staticProps, setStaticProps] = useState(null);
    const [invalidState, setInvalidState] = useState<
      "error" | "notFound" | null
    >(null);

    useEffect(() => {
      async function fetchStaticProps() {
        try {
          setInvalidState(null);
          const res = await getStaticProps({ params: router.query });
          if (res.notFound) {
            setInvalidState("notFound");
            return;
          }

          setStaticProps(res.props);
        } catch (err) {
          setInvalidState("error");
        }
      }
      fetchStaticProps();
    }, [router.query]);

    if (!staticProps) {
      // optional <Loading />
      return null;
    }

    if (invalidState === "notFound") {
      return <ErrorComponent statusCode={404} />;
    }

    if (invalidState === "error") {
      return <ErrorComponent statusCode={500} />;
    }

    return <Component {...staticProps} />;
  };
}
