import { notFound } from "next/navigation";
import { PrismaClient } from "@prisma/client";

import type { Block, ProjectConfig } from "@/features/editor/state/editorStore";
import { buildStaticHtml } from "@/features/export/buildStaticHtml";
import { getCachedPublicProject } from "@/features/projects/publicCache";
import PublicProjectPageClient from "./PublicProjectPageClient";

const prisma = new PrismaClient();

interface PageParams {
  // Next.js App Router 에서는 params 가 Promise 로 전달되므로
  // 서버 컴포넌트에서 사용하기 전에 await 로 한 번 풀어줘야 한다.
  params: Promise<{ slug: string }>;
}

// /p/[slug] 공개 페이지
// - slug 에 해당하는 Project 의 contentJson 을 불러와 buildStaticHtml 로 정적 HTML 을 생성한다.
// - Export ZIP 에 포함되는 index.html 과 동일한 app-root DOM 구조를 사용해 렌더링한다.
// - 인증 없이 접근 가능하며, 폼 제출은 /api/forms/submit 을 통해 정적 Export 와 동일하게 동작한다.
export default async function PublicProjectPage({ params }: PageParams) {
  // Next 가 넘겨주는 params 는 Promise 이므로, 먼저 await 해서 slug 를 꺼낸다.
  const resolvedParams = await params;
  const slugRaw = resolvedParams.slug ?? "";
  const slug = slugRaw.toString().trim();

  if (!slug) {
    notFound();
  }

  // 1차로 메모리 기반 퍼블릭 캐시에서 스냅샷을 조회한다.
  const cached = getCachedPublicProject(slug);

  let blocks: Block[];
  let title: string;

  if (cached) {
    blocks = cached.contentJson ?? [];
    title = cached.title ?? "";
  } else {
    const project = await prisma.project.findUnique({
      where: { slug },
      select: {
        title: true,
        slug: true,
        contentJson: true,
      },
    });

    if (!project) {
      notFound();
    }

    const rawContent = project.contentJson;
    let contentBlocks: Block[] = [];
    if (Array.isArray(rawContent)) {
      contentBlocks = rawContent as unknown as Block[];
    }
    blocks = contentBlocks;
    title = project.title;
  }

  // Export index.html 과 동일한 규칙으로 ProjectConfig 를 구성한다.
  const projectConfig: ProjectConfig = {
    title,
    slug,
    canvasPreset: "full",
    canvasBgColorHex: "#020617",
    bodyBgColorHex: "#020617",
  } as ProjectConfig;

  const fullHtml = buildStaticHtml(blocks, projectConfig);

  // buildStaticHtml 이 생성한 index.html 에서 <main> ... </main> 블록만 추출해 렌더링한다.
  // 이렇게 하면 Export index.html 과 동일한 main/app-root DOM 구조를 재사용할 수 있다.
  const mainMatch = fullHtml.match(/<main[\s\S]*?<\/main>/);
  const mainHtml = mainMatch ? mainMatch[0] : "";

  return <PublicProjectPageClient html={mainHtml} />;
}
