import { describe, it, expect, afterEach } from "vitest";
import { render, screen, cleanup } from "@testing-library/react";
import { PublicPageRenderer } from "@/features/editor/components/PublicPageRenderer";
import type { Block, SectionBlockProps, TextBlockProps } from "@/features/editor/state/editorStore";

// PublicPageRenderer 섹션/루트 레이아웃 TDD
// - Export 레이어의 pb-root / pb-section-* 구조와 개념적으로 대응되는 프리뷰 레이아웃을 고정한다.
// - 정확한 px 값 비교 대신, 주요 Tailwind 레이아웃 클래스 존재 여부를 검증한다.

describe("PublicPageRenderer - 섹션/루트 레이아웃", () => {
  afterEach(() => {
    cleanup();
  });

  const makeSectionWithText = (sectionOverride: Partial<SectionBlockProps> = {}, textOverride: Partial<TextBlockProps> = {}): Block[] => {
    const sectionProps: SectionBlockProps = {
      background: "default",
      paddingY: "md",
      columns: [{ id: "sec_layout_col_1", span: 12 }],
      maxWidthMode: "normal",
      gapX: "md",
      alignItems: "top",
      ...sectionOverride,
    } as SectionBlockProps;

    const textProps: TextBlockProps = {
      text: "섹션 레이아웃 텍스트",
      align: "left",
      size: "base",
      ...textOverride,
    } as TextBlockProps;

    const section: Block = {
      id: "sec_layout_1",
      type: "section",
      props: sectionProps,
    } as any;

    const text: Block = {
      id: "sec_layout_1_text",
      type: "text",
      sectionId: "sec_layout_1",
      columnId: "sec_layout_col_1",
      props: textProps,
    } as any;

    return [section, text];
  };

  it("섹션 레이아웃은 mx-auto / max-w / px-* 및 flex 컬럼/갭 구조로 렌더되어야 한다", () => {
    const blocks: Block[] = makeSectionWithText();

    render(<PublicPageRenderer blocks={blocks} />);

    const inner = screen.getByTestId("preview-section-inner") as HTMLDivElement;
    const columns = screen.getByTestId("preview-section-columns") as HTMLDivElement;

    // Export 의 pb-section-inner / pb-section-columns 에 대응되는 레이아웃 구조를 최소한으로 보장한다.
    expect(inner.className).toContain("mx-auto");
    expect(inner.className).toContain("px-4");
    expect(inner.className).toMatch(/max-w-/);

    expect(columns.className).toContain("flex");
    // gapX 기본값(md)에 대해 gap-8 이 사용되는 현재 구현을 고정한다.
    expect(columns.className).toContain("gap-8");

    // 컬럼 래퍼는 flex-col 과 일정한 세로 간격을 가진다.
    const columnWrapper = columns.querySelector("div.flex.flex-col") as HTMLDivElement | null;
    expect(columnWrapper).not.toBeNull();
    if (columnWrapper) {
      expect(columnWrapper.className).toContain("gap-4");
    }

    // 섹션 텍스트가 실제로 섹션 안에 렌더되는지 확인한다.
    const textEl = screen.getByText("섹션 레이아웃 텍스트");
    const section = textEl.closest("section");
    expect(section).not.toBeNull();
  });

  it("루트 블록은 상단 섹션 내 max-width 컨테이너 안에서 렌더되어야 한다", () => {
    const rootTextProps: TextBlockProps = {
      text: "루트 레이아웃 텍스트",
      align: "left",
      size: "base",
    } as TextBlockProps;

    const rootTextBlock: Block = {
      id: "root_layout_text",
      type: "text",
      props: rootTextProps,
    } as any;

    const sectionBlocks = makeSectionWithText();

    const blocks: Block[] = [rootTextBlock, ...sectionBlocks];

    render(<PublicPageRenderer blocks={blocks} />);

    const rootTextEl = screen.getByText("루트 레이아웃 텍스트") as HTMLParagraphElement;

    // 루트 텍스트는 상단 섹션(py-12) 안에 존재해야 한다.
    const rootSection = rootTextEl.closest("section");
    expect(rootSection).not.toBeNull();
    if (!rootSection) return;

    expect(rootSection.className).toContain("py-12");

    // 섹션 바로 아래의 max-width 컨테이너 구조를 확인한다.
    const innerContainer = rootSection.querySelector("div");
    expect(innerContainer).not.toBeNull();
    if (!innerContainer) return;

    const className = innerContainer.className;
    expect(className).toContain("mx-auto");
    expect(className).toContain("max-w-3xl");
    expect(className).toContain("px-4");
    expect(className).toContain("flex");
    expect(className).toContain("gap-4");
  });
});
