import nextDynamic from "next/dynamic";
import { fetchCMSPage } from "@/lib/cms-service/page";
import { transformCMSPage } from "@/lib/transformPage";
import { RenderBlocks } from "@/component/renderBlocks";
import Hero from "@/component/hero";
import RichText from "@/component/richText";
import CardSection from "@/component/cardSection";
import Footer from "@/component/footer";
import FloatingButtons from "@/component/floatingButtons";
import SnippetsInjector from "@/component/snippetsInjector";
import type { CMSBlock, FloatingButtonBlock } from "@/types";
import { notFound } from "next/navigation";
import { buildMetadataFromCMS } from "@/lib/cms-seo";

const ContactForm = nextDynamic(
  () => import("@/component/contactForm/contactForm.client"),
  { loading: () => <div className="h-64 animate-pulse bg-gray-50 rounded-xl" /> },
);

const GalleryCarousel = nextDynamic(
  () => import("@/component/gallery/gallery.client"),
  { loading: () => <div className="h-96 animate-pulse bg-gray-50" /> },
);

const blockComponents = {
  hero: Hero,
  introText: RichText,
  cards: CardSection,
  requestForm: ContactForm,
  carousel: GalleryCarousel,
  footer: Footer,
};

export const dynamic = "force-dynamic";

export async function generateMetadata({
  params,
}: {
  params: Promise<{ slug: string }>;
}) {
  try {
    const { slug } = await params;
    const cmsPayload = await fetchCMSPage(slug);
    return buildMetadataFromCMS(cmsPayload);
  } catch {
    return {};
  }
}

export default async function Page({
  params,
}: {
  params: Promise<{ slug: string }>;
}) {
  const { slug } = await params;
  let cmsPayload: any;
  try {
    cmsPayload = await fetchCMSPage(slug);
  } catch (error) {
    const message = error instanceof Error ? error.message : "";
    if (message.includes("(404)") || message.includes("NOT_FOUND")) {
      notFound();
    }
    throw error;
  }
  const isEmptyPayload =
    !cmsPayload ||
    (typeof cmsPayload === "object" &&
      !Array.isArray(cmsPayload) &&
      Object.keys(cmsPayload).length === 0);

  if (isEmptyPayload) {
    notFound();
  }
  const pageData = transformCMSPage(cmsPayload);
  const floatingBlock = pageData.layout.find(
    (b): b is FloatingButtonBlock => b.blockType === "floatingButton",
  );

  return (
    <main>
      <SnippetsInjector snippets={pageData.snippets} renderTop />
      {floatingBlock && <FloatingButtons data={floatingBlock} />}
      <RenderBlocks
        blocks={pageData.layout as CMSBlock[]}
        blockComponents={blockComponents}
      />
      <SnippetsInjector snippets={pageData.snippets} renderBottom />
    </main>
  );
}
