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

// 폼 필드 스타일 TDD
// - formInput: 색상/패딩/너비/둥글기 스타일
// - formSelect: 색상/패딩/너비/둥글기 스타일
// - formCheckbox/formRadio: 옵션 컨테이너 색상/패딩/둥글기 스타일

function getFirstLabel(root: HTMLElement): HTMLLabelElement {
  const label = root.querySelector("label");
  if (!label) {
    throw new Error("label element not found");
  }
  return label as HTMLLabelElement;
}

describe("PublicPageRenderer - 폼 필드 스타일", () => {
  afterEach(() => {
    cleanup();
  });

  it("formInput 블록은 색상/패딩/너비/둥글기 스타일을 반영해야 한다", () => {
    const blocks: Block[] = [
      {
        id: "form_input_styles",
        type: "formInput",
        props: {
          label: "이메일",
          formFieldName: "email",
          align: "center",
          widthMode: "fixed",
          widthPx: 320,
          paddingX: 16,
          paddingY: 8,
          textColorCustom: "#112233",
          fillColorCustom: "#123456",
          strokeColorCustom: "#ff0000",
          borderRadius: "lg",
        } as any,
      },
    ];

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

    const wrapper = getByTestId("preview-form-input-wrapper") as HTMLElement;
    const input = wrapper.querySelector('[data-testid="preview-form-input"]') as HTMLElement | null;
    expect(input).not.toBeNull();

    // 정렬
    expect((input as HTMLInputElement).style.textAlign).toBe("center");
    // width: 320px / 16 = 20em
    expect((input as HTMLInputElement).style.width).toBe("20em");
    // padding-inline/block: 16px/8px -> 1em / 0.5em
    expect((input as HTMLInputElement).style.paddingInline).toBe("1em");
    expect((input as HTMLInputElement).style.paddingBlock).toBe("0.5em");
    // 색상: hex -> rgb 변환
    expect((input as HTMLInputElement).style.color).toBe("rgb(17, 34, 51)");
    expect((input as HTMLInputElement).style.backgroundColor).toBe("rgb(18, 52, 86)");
    expect((input as HTMLInputElement).style.borderColor).toBe("rgb(255, 0, 0)");
    // borderRadius: lg -> 6px
    expect((input as HTMLInputElement).style.borderRadius).toBe("6px");
  });

  it("formSelect 블록은 색상/패딩/너비/둥글기 스타일을 반영해야 한다", () => {
    const blocks: Block[] = [
      {
        id: "form_select_styles",
        type: "formSelect",
        props: {
          label: "카테고리",
          formFieldName: "category",
          options: [
            { label: "A", value: "a" },
            { label: "B", value: "b" },
          ],
          widthMode: "fixed",
          widthPx: 240,
          paddingX: 16,
          paddingY: 8,
          textColorCustom: "#00ff00",
          fillColorCustom: "#123456",
          strokeColorCustom: "#ff0000",
          borderRadius: "lg",
        } as any,
      },
    ];

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

    const wrapper = getByTestId("preview-form-select") as HTMLElement;
    const select = wrapper.querySelector("select") as HTMLSelectElement | null;
    expect(select).not.toBeNull();

    // width: 240px / 16 = 15em
    expect(wrapper.style.width).toBe("15em");
    // padding-inline/block: 16px/8px -> 1em / 0.5em
    expect(select!.style.paddingInline).toBe("1em");
    expect(select!.style.paddingBlock).toBe("0.5em");
    // 색상
    expect(select!.style.color).toBe("rgb(0, 255, 0)");
    expect(select!.style.backgroundColor).toBe("rgb(18, 52, 86)");
    expect(select!.style.borderColor).toBe("rgb(255, 0, 0)");
    // 둥글기
    expect(select!.style.borderRadius).toBe("6px");
  });

  it("formCheckbox 블록은 옵션 컨테이너에 색상/패딩/둥글기 스타일을 반영해야 한다", () => {
    const blocks: Block[] = [
      {
        id: "form_checkbox_styles",
        type: "formCheckbox",
        props: {
          groupLabel: "옵션들",
          formFieldName: "features",
          options: [{ label: "옵션 1", value: "opt1" }],
          widthMode: "fixed",
          widthPx: 320,
          paddingX: 8,
          paddingY: 4,
          optionGapPx: 16,
          textColorCustom: "#ffffff",
          fillColorCustom: "#123456",
          strokeColorCustom: "#ff0000",
          borderRadius: "lg",
        } as any,
      },
    ];

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

    const group = getByTestId("preview-form-checkbox-group") as HTMLElement;
    const firstLabel = getFirstLabel(group);

    // width: 320px / 16 = 20em
    expect(group.style.width).toBe("20em");
    // 옵션 간 간격: 16px -> 1em
    const optionsContainer = group.querySelector('[data-testid="preview-form-checkbox-options"]') as HTMLElement | null;
    expect(optionsContainer).not.toBeNull();
    expect(optionsContainer!.style.rowGap).toBe("1em");

    // 옵션 컨테이너 스타일: padding, 배경, 보더, 둥글기
    expect(firstLabel.style.paddingInline).toBe("0.5em");
    expect(firstLabel.style.paddingBlock).toBe("0.25em");
    expect(firstLabel.style.backgroundColor).toBe("rgb(18, 52, 86)");
    expect(firstLabel.style.borderColor).toBe("rgb(255, 0, 0)");
    expect(firstLabel.style.borderRadius).toBe("6px");
  });

  it("formRadio 블록은 옵션 컨테이너에 색상/패딩/둥글기 스타일을 반영해야 한다", () => {
    const blocks: Block[] = [
      {
        id: "form_radio_styles",
        type: "formRadio",
        props: {
          groupLabel: "플랜",
          formFieldName: "plan",
          options: [{ label: "플랜 A", value: "a" }],
          widthMode: "fixed",
          widthPx: 320,
          paddingX: 8,
          paddingY: 4,
          optionGapPx: 16,
          textColorCustom: "#ffffff",
          fillColorCustom: "#123456",
          strokeColorCustom: "#ff0000",
          borderRadius: "lg",
        } as any,
      },
    ];

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

    const group = getByTestId("preview-form-radio-group") as HTMLElement;
    const firstLabel = getFirstLabel(group);

    // width: 320px / 16 = 20em
    expect(group.style.width).toBe("20em");
    // 옵션 간 간격: 16px -> 1em
    const optionsContainer = group.querySelector('[data-testid="preview-form-radio-options"]') as HTMLElement | null;
    expect(optionsContainer).not.toBeNull();
    expect(optionsContainer!.style.rowGap).toBe("1em");

    // 옵션 컨테이너 스타일: padding, 배경, 보더, 둥글기
    expect(firstLabel.style.paddingInline).toBe("0.5em");
    expect(firstLabel.style.paddingBlock).toBe("0.25em");
    expect(firstLabel.style.backgroundColor).toBe("rgb(18, 52, 86)");
    expect(firstLabel.style.borderColor).toBe("rgb(255, 0, 0)");
    expect(firstLabel.style.borderRadius).toBe("6px");
  });
});
