import { describe, it, expect, afterEach } from "vitest";
import { render, screen, cleanup } from "@testing-library/react";
import type { Block, ProjectConfig } from "@/features/editor/state/editorStore";
import { EditorCanvas, EditorCanvasDragPreview } from "@/app/editor/EditorCanvas";
import { LocaleProvider } from "@/features/i18n/LocaleProvider";
import { DEFAULT_LOCALE } from "@/features/i18n/locale";

// 에디터 캔버스/페이지 배경색 적용 규칙에 대한 최소 TDD
// - canvasBgColorHex: 실제 캔버스 영역(editor-canvas-inner)의 배경색
// - bodyBgColorHex: 에디터 내 페이지 배경(캔버스 바깥 래퍼)의 배경색

afterEach(() => {
  cleanup();
});

describe("EditorCanvas - 캔버스/페이지 배경색", () => {
  const baseProjectConfig: ProjectConfig = {
    title: "배경 테스트",
    slug: "bg-test",
    canvasPreset: "full",
    canvasBgColorHex: "#111111",
    bodyBgColorHex: "#222222",
  };

  const baseProps = {
    blocks: [] as Block[],
    rootBlocks: [] as Block[],
    selectedBlockId: null as string | null,
    editingBlockId: null as string | null,
    editingText: "",
    activeDragId: null as string | null,
    sensors: null as any,
    onCanvasEmptyClick: () => {},
    renderBlocks: () => null as any,
    handleDragStart: () => {},
    handleDragEnd: () => {},
    handleDragCancel: () => {},
    projectConfig: baseProjectConfig,
  };

  it("canvasBgColorHex 는 editor-canvas-inner 배경색에 적용되어야 한다", () => {
    render(
      <LocaleProvider initialLocale={DEFAULT_LOCALE}>
        <EditorCanvas {...baseProps} />
      </LocaleProvider>,
    );

    const inner = screen.getByTestId("editor-canvas-inner") as HTMLElement;

    expect(inner.style.backgroundColor).toBe("rgb(17, 17, 17)");
  });

  it("blocks 가 없을 때 en 로케일에서는 영어 안내 문구를 표시해야 한다", () => {
    render(
      <LocaleProvider initialLocale={DEFAULT_LOCALE}>
        <EditorCanvas {...baseProps} />
      </LocaleProvider>,
    );

    const hint = screen.getByText(
      'Click the "Text" button on the left to add your first block.',
    );
    expect(hint.textContent).toBe(
      'Click the "Text" button on the left to add your first block.',
    );
  });

  it("bodyBgColorHex 는 editor-canvas 바깥 래퍼(editor-canvas)의 배경색에 적용되어야 한다", () => {
    const { container } = render(
      <LocaleProvider initialLocale={DEFAULT_LOCALE}>
        <EditorCanvas {...baseProps} />
      </LocaleProvider>,
    );

    const outer = container.querySelector('[data-testid="editor-canvas"]') as HTMLElement | null;

    expect(outer).not.toBeNull();
    expect(outer!.style.backgroundColor).toBe("rgb(34, 34, 34)");
  });

  it("canvasPreset / canvasWidthPx 에 따라 editor-canvas-inner 의 maxWidth 가 설정되어야 한다", () => {
    const renderWithConfig = (partial: Partial<ProjectConfig>) => {
      const projectConfig = { ...baseProjectConfig, ...partial } as ProjectConfig;
      const { getByTestId, unmount } = render(
        <LocaleProvider initialLocale={DEFAULT_LOCALE}>
          <EditorCanvas {...baseProps} projectConfig={projectConfig} />
        </LocaleProvider>,
      );
      const inner = getByTestId("editor-canvas-inner") as HTMLElement;
      const maxWidth = inner.style.maxWidth;
      unmount();
      return maxWidth;
    };

    expect(renderWithConfig({ canvasPreset: "mobile", canvasWidthPx: 390 })).toBe("390px");
    expect(renderWithConfig({ canvasPreset: "tablet", canvasWidthPx: 768 })).toBe("768px");
    expect(renderWithConfig({ canvasPreset: "desktop", canvasWidthPx: 1200 })).toBe("1200px");

    // full 프리셋에서 canvasWidthPx 가 없으면 maxWidth 는 비워져 있어야 한다.
    expect(renderWithConfig({ canvasPreset: "full", canvasWidthPx: undefined })).toBe("");

    // custom 프리셋에서는 canvasWidthPx 값이 그대로 사용된다.
    expect(renderWithConfig({ canvasPreset: "custom", canvasWidthPx: 1024 })).toBe("1024px");
  });

  it("DragOverlay 프리뷰는 라이트/다크 듀얼 테마 크롬을 사용해야 한다", () => {
    const block: Block = {
      id: "drag_1",
      type: "text",
      props: {
        text: "드래그 미리보기",
        align: "left",
        size: "base",
      },
    } as any;

    const { container } = render(
      <LocaleProvider initialLocale={DEFAULT_LOCALE}>
        <EditorCanvasDragPreview block={block} />
      </LocaleProvider>,
    );

    const overlay = container.querySelector(
      "div.pointer-events-none.rounded.border",
    ) as HTMLElement | null;
    expect(overlay).not.toBeNull();

    const className = overlay!.getAttribute("class") ?? "";
    expect(className).toContain("border-sky-500");
    expect(className).toContain("bg-white");
    expect(className).toContain("text-slate-900");
    expect(className).toContain("dark:bg-slate-900");
    expect(className).toContain("dark:text-slate-100");
  });

  it("en 로케일에서는 EditorCanvasDragPreview 의 텍스트 블록 fallback 라벨이 영어로 표시되어야 한다", () => {
    const block: Block = {
      id: "text_fallback_1",
      type: "text",
      props: {
        text: "",
        align: "left",
        size: "base",
      },
    } as any;

    render(
      <LocaleProvider initialLocale={DEFAULT_LOCALE}>
        <EditorCanvasDragPreview block={block} />
      </LocaleProvider>,
    );

    const fallbackLabel = screen.getByText("Text block");
    expect(fallbackLabel.textContent).toBe("Text block");
  });
});
