import { describe, it, expect } from "vitest";
import { expectNoPxInStyleParts } from "./styleInvariants";
import {
  computeImageExportStyles,
  computeImageEditorTokens,
  computeImagePublicTokens,
} from "@/features/editor/utils/imageHelpers";
import type { ImageBlockProps } from "@/features/editor/state/editorStore";

describe("imageHelpers.computeImageExportStyles", () => {
  it("기본 값에서는 배경/너비 없이 border-radius 8px 를 사용해야 한다(md 토큰)", () => {
    const { wrapperStyleParts, imgStyleParts } = computeImageExportStyles({});

    expect(wrapperStyleParts.length).toBe(0);
    expect(imgStyleParts).toContain("border-radius:8px");
  });

  it("backgroundColorCustom 이 있으면 wrapperStyle 에 background-color 스타일을 추가해야 한다", () => {
    const { wrapperStyleParts } = computeImageExportStyles({
      backgroundColorCustom: "#123456",
    });

    expect(wrapperStyleParts).toContain("background-color:#123456");
  });

  it("widthMode=fixed 이고 widthPx 가 양수이면 이미지 width 스타일을 추가해야 한다", () => {
    const { imgStyleParts } = computeImageExportStyles({
      widthMode: "fixed",
      widthPx: 320,
    });

    expect(imgStyleParts).toContain("width:20em");
  });

  it("borderRadius 토큰이 full 이면 border-radius 9999px 를 사용해야 한다", () => {
    const { imgStyleParts } = computeImageExportStyles({
      borderRadius: "full",
    });

    expect(imgStyleParts).toContain("border-radius:9999px");
  });

  it("borderRadiusPx 가 지정되면 토큰 대신 해당 값을 px 로 사용해야 한다", () => {
    const { imgStyleParts } = computeImageExportStyles({
      borderRadius: "lg",
      borderRadiusPx: 20,
    });

    expect(imgStyleParts).toContain("border-radius:20px");
  });

  it("Export 이미지 스타일에는 border-radius 를 제외하고 px 단위 값이 포함되지 않아야 한다", () => {
    const { wrapperStyleParts, imgStyleParts } = computeImageExportStyles({
      backgroundColorCustom: "#123456",
      widthMode: "fixed",
      widthPx: 320,
      borderRadius: "lg",
    });

    expectNoPxInStyleParts(wrapperStyleParts);
    expectNoPxInStyleParts(imgStyleParts, { allowPatterns: [/border-radius:\d+px/] });
  });
});

describe("computeImageEditorTokens", () => {
  it("기본 값에서는 widthPx 없이 borderRadius 8px 를 사용해야 한다(md 토큰)", () => {
    const tokens = computeImageEditorTokens({});

    expect(tokens.widthPx).toBeUndefined();
    expect(tokens.radiusPx).toBe(8);
  });

  it("widthMode=fixed 이고 widthPx 가 양수이면 widthPx 토큰을 그대로 사용해야 한다", () => {
    const tokens = computeImageEditorTokens({
      widthMode: "fixed",
      widthPx: 320,
    });

    expect(tokens.widthPx).toBe(320);
  });

  it("borderRadius 토큰이 full 이면 radiusPx 9999 를 사용해야 한다", () => {
    const tokens = computeImageEditorTokens({
      borderRadius: "full",
    });

    expect(tokens.radiusPx).toBe(9999);
  });

  it("borderRadiusPx 가 지정되면 토큰 대신 해당 radiusPx 를 사용해야 한다", () => {
    const tokens = computeImageEditorTokens({
      borderRadius: "lg",
      borderRadiusPx: 24,
    });

    expect(tokens.radiusPx).toBe(24);
  });
});

describe("imageHelpers.computeImagePublicTokens", () => {
  const baseProps: ImageBlockProps = {
    src: "/images/example.png",
    alt: "이미지",
    align: "center",
    widthMode: "auto",
  };

  it("backgroundColorCustom 이 설정된 경우에만 wrapperStyle.backgroundColor 를 설정해야 한다", () => {
    const tokensWithBg = computeImagePublicTokens({
      ...baseProps,
      backgroundColorCustom: "#123456",
    });

    expect(tokensWithBg.wrapperStyle.backgroundColor).toBe("#123456");

    const tokensWithoutBg = computeImagePublicTokens({
      ...baseProps,
      backgroundColorCustom: undefined,
    });

    expect(tokensWithoutBg.wrapperStyle.backgroundColor).toBeUndefined();
  });

  it("widthMode 가 fixed 이고 widthPx 가 설정된 경우 imageStyle.width 는 em 단위로 설정되어야 한다", () => {
    const tokens = computeImagePublicTokens({
      ...baseProps,
      widthMode: "fixed",
      widthPx: 480,
    });

    expect(tokens.imageStyle.width).toBe("30em");
  });

  it("borderRadiusPx 가 설정된 경우 imageStyle.borderRadius 는 em 단위로 설정되어야 한다", () => {
    const tokens = computeImagePublicTokens({
      ...baseProps,
      borderRadiusPx: 32,
    });

    expect(tokens.imageStyle.borderRadius).toBe("2em");
  });
});
