import { getClient } from "@/app/client";
import { uncached } from "@/lib/revalidation";
import { PreviewBanner } from "@/components/general/PreviewBanner";
import {
  AssociationIndexView,
  loadAssociationIndexProps,
} from "@/components/associations/AssociationIndexView";
import {
  AssociationPageView,
  loadAssociationPageProps,
} from "@/components/associations/AssociationPageView";
import {
  ContactIndexView,
  loadContactIndexProps,
} from "@/components/contact/ContactIndexView";
import {
  EventIndexView,
  loadEventIndexProps,
} from "@/components/events/EventIndexView";
import {
  EventPageView,
  loadEventPageProps,
} from "@/components/events/EventPageView";
import {
  GenericPageView,
  loadGenericPageProps,
} from "@/components/general/GenericPageView";
import {
  HomePageView,
  loadHomePageProps,
} from "@/components/home/HomePageView";
import {
  NewsIndexView,
  loadNewsIndexProps,
} from "@/components/news/NewsIndexView";
import {
  NewsPageView,
  loadNewsPageProps,
} from "@/components/news/NewsPageView";
import {
  SponsorsPageView,
  loadSponsorsPageProps,
} from "@/components/sponsor/SponsorsPageView";
import {
  StudioPageView,
  loadStudioPageProps,
} from "@/components/studio/StudioPageView";
import {
  VenueIndexView,
  loadVenueIndexProps,
} from "@/components/venues/VenueIndexView";
import {
  VenuePageView,
  loadVenuePageProps,
} from "@/components/venues/VenuePageView";
import {
  VenueRentalIndexView,
  loadVenueRentalIndexProps,
} from "@/components/venues/VenueRentalIndexView";
import { graphql } from "@/gql";
import {
  AssociationFragment,
  AssociationIndexFragment,
  ContactIndexFragment,
  EventFragment,
  GenericFragment,
  HomeFragment,
  NewsFragment,
  NewsIndexFragment,
  SponsorsPageFragment,
  StudioFragment,
  VenueFragment,
  VenueIndexFragment,
  VenueRentalIndexFragment,
} from "@/gql/graphql";
import { cookies } from "next/headers";
export const dynamic = "force-dynamic";
export const revalidate = 0;

const previewPageQuery = graphql(`
  query previewPage($token: String!) {
    page: page(token: $token) {
      __typename
      ... on GenericPage {
        ...Generic
      }
      ... on StudioPage {
        ...Studio
      }
      ... on SponsorsPage {
        ...SponsorsPage
      }
      ... on HomePage {
        ...Home
      }
      ... on EventPage {
        ...Event
      }
      ... on NewsPage {
        ...News
      }
      ... on AssociationPage {
        ...Association
      }
      ... on VenuePage {
        ...Venue
      }
      ... on NewsIndex {
        ...NewsIndex
      }
      ... on AssociationIndex {
        ...AssociationIndex
      }
      ... on VenueIndex {
        ...VenueIndex
      }
      ... on VenueRentalIndex {
        ...VenueRentalIndex
      }
      ... on ContactIndex {
        ...ContactIndex
      }
    }
  }
`);

function ExpiredPreview() {
  return (
    <main className="site-main" id="main">
      <h1>Preview session expired</h1>
      <p>Click Preview again in the Wagtail admin to start a new session.</p>
    </main>
  );
}

function UnsupportedType({ typename }: { typename: string }) {
  return (
    <main className="site-main" id="main">
      <h1>Preview not available</h1>
      <p>
        Type <code>{typename}</code> cannot be previewed.
      </p>
    </main>
  );
}

export default async function PreviewRender() {
  const token = (await cookies()).get("preview-token")?.value;
  if (!token) {
    return <ExpiredPreview />;
  }

  const { data, error } = await getClient().query(
    previewPageQuery,
    { token },
    uncached
  );
  if (error) {
    throw new Error(error.message);
  }
  if (!data?.page) {
    return <ExpiredPreview />;
  }

  const page = data.page;
  const view = await (async () => {
    switch (page.__typename) {
      case "GenericPage": {
        const props = await loadGenericPageProps({
          pageOverride: page as GenericFragment,
        });
        return <GenericPageView {...props!} />;
      }
      case "StudioPage": {
        const props = await loadStudioPageProps({
          pageOverride: page as StudioFragment,
        });
        return <StudioPageView {...props} />;
      }
      case "SponsorsPage": {
        const props = await loadSponsorsPageProps({
          pageOverride: page as SponsorsPageFragment,
        });
        return <SponsorsPageView {...props} />;
      }
      case "EventPage": {
        const props = await loadEventPageProps({
          eventOverride: page as EventFragment,
        });
        return <EventPageView {...props!} />;
      }
      case "NewsPage": {
        const props = await loadNewsPageProps({
          newsOverride: page as NewsFragment,
        });
        return <NewsPageView {...props!} />;
      }
      case "AssociationPage": {
        const props = await loadAssociationPageProps({
          associationOverride: page as AssociationFragment,
        });
        return <AssociationPageView {...props!} />;
      }
      case "VenuePage": {
        const props = await loadVenuePageProps({
          venueOverride: page as VenueFragment,
        });
        return <VenuePageView {...props!} />;
      }
      case "HomePage": {
        const props = await loadHomePageProps({
          homeOverride: page as HomeFragment,
        });
        return <HomePageView {...props} />;
      }
      case "EventIndex": {
        const props = await loadEventIndexProps();
        return <EventIndexView {...props} />;
      }
      case "NewsIndex": {
        const props = await loadNewsIndexProps({
          indexOverride: page as NewsIndexFragment,
        });
        return <NewsIndexView {...props} />;
      }
      case "AssociationIndex": {
        const props = await loadAssociationIndexProps({
          indexOverride: page as AssociationIndexFragment,
        });
        return <AssociationIndexView {...props} />;
      }
      case "VenueIndex": {
        const props = await loadVenueIndexProps({
          indexOverride: page as VenueIndexFragment,
        });
        return <VenueIndexView {...props} />;
      }
      case "VenueRentalIndex": {
        const props = await loadVenueRentalIndexProps({
          indexOverride: page as VenueRentalIndexFragment,
        });
        return <VenueRentalIndexView {...props} />;
      }
      case "ContactIndex": {
        const props = await loadContactIndexProps({
          indexOverride: page as ContactIndexFragment,
        });
        return <ContactIndexView {...props} />;
      }
      default:
        return <UnsupportedType typename={page.__typename ?? "unknown"} />;
    }
  })();

  return (
    <>
      <PreviewBanner />
      {view}
    </>
  );
}
