import { graphql } from "@/gql";
import { GenericFragment } from "@/gql/graphql";
import { getClient } from "@/app/client";
import { Metadata, ResolvingMetadata } from "next";
import { notFound } from "next/navigation";
import { PageHeader } from "@/components/general/PageHeader";
import { PageContent } from "@/components/general/PageContent";
import { BgPig } from "@/components/general/BgPig";
import { getSeoMetadata } from "@/lib/seo";

export const dynamicParams = false;

const GenericFragmentDefinition = graphql(`
  fragment Generic on GenericPage {
    __typename
    id
    urlPath
    seoTitle
    searchDescription
    title
    lead
    pig
    body {
      ...Blocks
    }
  }
`);

const genericPageByUrlPathQuery = graphql(`
  query genericPageByUrl($urlPath: String!) {
    page: page(contentType: "generic.GenericPage", urlPath: $urlPath) {
      ... on GenericPage {
        ...Generic
      }
    }
  }
`);

function getWagtailUrlPath(url: string[]): string {
  // for the page /foo/bar we need to look for `/home/foo/bar/`
  return `/home/${url.join("/")}/`;
}

export async function generateStaticParams() {
  const allGenericSlugsQuery = graphql(`
    query allGenericSlugs {
      pages(contentType: "generic.GenericPage") {
        id
        urlPath
      }
    }
  `);
  const { data, error } = await getClient().query(allGenericSlugsQuery, {});
  if (error) {
    throw new Error(error.message);
  }
  if (!data?.pages) {
    throw new Error("Failed to generate static params for generic subpages");
  }

  return data.pages.map((page: any) => {
    // wagtail-grapple prepends the home page slug to the full path on multisite setups
    // we also strip the trailing slash
    const urlPath: string[] = page.urlPath
      .replace(/\/home\//, "")
      .replace(/\/$/, "")
      .split("/");
    return {
      url: urlPath,
    };
  });
}

type Params = Promise<{ url: string[] }>;

export async function generateMetadata(
  { params }: { params: Params },
  parent: ResolvingMetadata
): Promise<Metadata | null> {
  const { url } = await params;
  const urlPath = getWagtailUrlPath(url);
  const { data, error } = await getClient().query(genericPageByUrlPathQuery, {
    urlPath: urlPath,
  });

  if (error) {
    throw new Error(error.message);
  }
  if (!data?.page) {
    return null;
  }

  const page = data.page as GenericFragment;
  const metadata = await getSeoMetadata(page, parent);
  return metadata;
}

export default async function Page({ params }: { params: Params }) {
  const { url } = await params;
  const urlPath = getWagtailUrlPath(url);
  const { data, error } = await getClient().query(genericPageByUrlPathQuery, {
    urlPath: urlPath,
  });
  if (error) {
    throw new Error(error.message);
  }

  if (!data?.page) {
    return notFound();
  }

  const page = data?.page as GenericFragment;

  return (
    <>
      <main className="site-main" id="main">
        <PageHeader heading={page.title} lead={page.lead} />
        <PageContent blocks={page.body} />
      </main>
      {page.pig && <BgPig type={page.pig} color="white" />}
    </>
  );
}
