import type { CSSProperties } from "react";
import type { ButtonBlockProps } from "@/features/editor/state/editorStore";

export type ButtonAlign = "left" | "center" | "right" | null | undefined;
export type ButtonSize = "xs" | "sm" | "md" | "lg" | "xl" | null | undefined;
export type ButtonVariant = "solid" | "outline" | "ghost" | null | undefined;
export type ButtonColorPalette = "primary" | "muted" | "danger" | "success" | "neutral" | null | undefined;
export type ButtonRadius = "none" | "sm" | "md" | "lg" | "full" | null | undefined;

export interface ButtonStyleInput {
  align?: ButtonAlign;
  size?: ButtonSize;
  variant?: ButtonVariant;
  colorPalette?: ButtonColorPalette;
  borderRadius?: ButtonRadius;
  fullWidth?: boolean | null | undefined;
  widthMode?: "auto" | "full" | "fixed" | null | undefined;
  widthPx?: number | null | undefined;
  paddingX?: number | null | undefined;
  paddingY?: number | null | undefined;
  fillColorCustom?: string | null | undefined;
  strokeColorCustom?: string | null | undefined;
  textColorCustom?: string | null | undefined;
}

export interface ButtonPbTokens {
  alignClass: string;
  sizeClass: string;
  variantClass: string;
  radiusClass: string;
  inlineStyles: string[];
}

export function computeButtonPbTokens(input: ButtonStyleInput): ButtonPbTokens {
  const align = input.align === "center" ? "center" : input.align === "right" ? "right" : "left";
  const alignClass =
    align === "center" ? "pb-text-center" : align === "right" ? "pb-text-right" : "pb-text-left";

  const sizeToken = (input.size as ButtonSize | null) ?? "md";
  const sizeMap: Record<Exclude<ButtonSize, null | undefined>, string> = {
    xs: "pb-btn-size-xs",
    sm: "pb-btn-size-sm",
    md: "pb-btn-size-md",
    lg: "pb-btn-size-lg",
    xl: "pb-btn-size-xl",
  };
  const sizeClass = sizeMap[sizeToken as Exclude<ButtonSize, null | undefined>] ?? "pb-btn-size-md";

  const variant = (input.variant as ButtonVariant | null) ?? "solid";
  const palette = (input.colorPalette as ButtonColorPalette | null) ?? "primary";
  const variantClass = `pb-btn-variant-${variant}-${palette}`;

  const radiusToken = (input.borderRadius as ButtonRadius | null) ?? "md";
  const radiusMap: Record<Exclude<ButtonRadius, null | undefined>, string> = {
    none: "pb-btn-radius-none",
    sm: "pb-btn-radius-sm",
    md: "pb-btn-radius-md",
    lg: "pb-btn-radius-lg",
    full: "pb-btn-radius-full",
  };
  const radiusClass = radiusMap[radiusToken as Exclude<ButtonRadius, null | undefined>] ?? "";

  const inlineStyles: string[] = [];

  const widthMode = input.widthMode ?? (input.fullWidth ? "full" : "auto");
  if (widthMode === "fixed" && typeof input.widthPx === "number" && input.widthPx > 0) {
    inlineStyles.push(`width:${pxToEm(input.widthPx)}`);
  }

  if (typeof input.paddingX === "number") {
    const paddingInline = pxToEm(input.paddingX);
    inlineStyles.push(`padding-left:${paddingInline}`);
    inlineStyles.push(`padding-right:${paddingInline}`);
  }

  if (typeof input.paddingY === "number") {
    const paddingBlock = pxToEm(input.paddingY);
    inlineStyles.push(`padding-top:${paddingBlock}`);
    inlineStyles.push(`padding-bottom:${paddingBlock}`);
  }

  if (input.fillColorCustom && input.fillColorCustom.trim() !== "") {
    inlineStyles.push(`background-color:${input.fillColorCustom.trim()}`);
  }

  if (input.strokeColorCustom && input.strokeColorCustom.trim() !== "") {
    inlineStyles.push(`border-color:${input.strokeColorCustom.trim()}`);
  }

  if (input.textColorCustom && input.textColorCustom.trim() !== "") {
    inlineStyles.push(`color:${input.textColorCustom.trim()}`);
  }

  return {
    alignClass,
    sizeClass,
    variantClass,
    radiusClass,
    inlineStyles,
  };
}

// 퍼블릭 렌더러용 버튼 스타일 토큰
export interface ButtonPublicTokens {
  alignClass: string;
  widthClass: string;
  styleOverrides: CSSProperties;
}

const pxToEm = (px: number, base = 16) => `${px / base}em`;

const convertPxStringToEm = (value?: string | null) => {
  if (!value) return null;
  const match = value.trim().match(/-?\d+(?:\.\d+)?/);
  if (!match) return null;
  const px = parseFloat(match[0]);
  if (!Number.isFinite(px)) return null;
  return pxToEm(px);
};

export function computeButtonPublicTokens(props: ButtonBlockProps): ButtonPublicTokens {
  const align = props.align ?? "left";
  const alignClass =
    align === "center" ? "text-center" : align === "right" ? "text-right" : "text-left";

  const styleOverrides: CSSProperties = {};

  // 폰트 크기: fontSizeCustom(px)는 em 으로 변환, 그 외는 그대로 사용
  const fontSizeEm = convertPxStringToEm(props.fontSizeCustom);
  if (fontSizeEm) {
    styleOverrides.fontSize = fontSizeEm;
  }

  // lineHeightCustom 은 px 단위든 아니든 그대로 사용 (기존 PublicPageRenderer 로직 유지)
  if (props.lineHeightCustom && props.lineHeightCustom.trim() !== "") {
    styleOverrides.lineHeight = props.lineHeightCustom;
  }

  // letterSpacingCustom 은 px 인 경우만 em 으로 변환, 그 외는 그대로 사용
  if (props.letterSpacingCustom && props.letterSpacingCustom.trim() !== "") {
    const letterSpacing = props.letterSpacingCustom.trim();
    if (letterSpacing.endsWith("px")) {
      const emValue = convertPxStringToEm(letterSpacing);
      if (emValue) {
        styleOverrides.letterSpacing = emValue;
      }
    } else {
      styleOverrides.letterSpacing = letterSpacing;
    }
  }

  const widthMode = props.widthMode ?? (props.fullWidth ? "full" : "auto");
  if (widthMode === "fixed" && typeof props.widthPx === "number" && props.widthPx > 0) {
    styleOverrides.width = pxToEm(props.widthPx);
  }

  if (typeof props.paddingX === "number" && props.paddingX >= 0) {
    styleOverrides.paddingInline = pxToEm(props.paddingX);
  }

  if (typeof props.paddingY === "number" && props.paddingY >= 0) {
    styleOverrides.paddingBlock = pxToEm(props.paddingY);
  }

  if (props.fillColorCustom && props.fillColorCustom.trim() !== "") {
    styleOverrides.backgroundColor = props.fillColorCustom;
  }

  if (props.strokeColorCustom && props.strokeColorCustom.trim() !== "") {
    styleOverrides.borderColor = props.strokeColorCustom;
    styleOverrides.borderWidth = "1px";
    styleOverrides.borderStyle = "solid";
  }

  if (props.textColorCustom && props.textColorCustom.trim() !== "") {
    styleOverrides.color = props.textColorCustom;
  }

  const radiusToken = props.borderRadius ?? "md";
  const radiusPx =
    radiusToken === "none"
      ? 0
      : radiusToken === "sm"
        ? 4
        : radiusToken === "lg"
          ? 12
          : radiusToken === "full"
            ? 9999
            : 8;
  styleOverrides.borderRadius = radiusPx === 9999 ? "9999px" : pxToEm(radiusPx);

  const widthClass = widthMode === "full" ? "w-full" : "";

  return {
    alignClass,
    widthClass,
    styleOverrides,
  };
}

export interface ButtonEditorTokens {
  wrapperWidthClass: string;
  buttonStyle: CSSProperties;
}

export function computeButtonEditorTokens(props: ButtonBlockProps): ButtonEditorTokens {
  const baseFullWidth = props.fullWidth ?? false;
  const widthMode = props.widthMode ?? (baseFullWidth ? "full" : "auto");
  const isFullWidth = widthMode === "full" || baseFullWidth;

  const wrapperWidthClass = isFullWidth ? "w-full" : "inline-block";

  const buttonStyle: CSSProperties = {};

  if (props.fontSizeCustom && props.fontSizeCustom.trim() !== "") {
    buttonStyle.fontSize = props.fontSizeCustom;
  }
  if (props.lineHeightCustom && props.lineHeightCustom.trim() !== "") {
    buttonStyle.lineHeight = props.lineHeightCustom;
  }
  if (props.letterSpacingCustom && props.letterSpacingCustom.trim() !== "") {
    buttonStyle.letterSpacing = props.letterSpacingCustom;
  }

  if (props.fillColorCustom && props.fillColorCustom.trim() !== "") {
    buttonStyle.backgroundColor = props.fillColorCustom;
  }
  if (props.strokeColorCustom && props.strokeColorCustom.trim() !== "") {
    buttonStyle.borderColor = props.strokeColorCustom;
  }
  if (props.textColorCustom && props.textColorCustom.trim() !== "") {
    buttonStyle.color = props.textColorCustom;
  }

  if (widthMode === "fixed" && typeof props.widthPx === "number" && props.widthPx > 0) {
    buttonStyle.width = `${props.widthPx}px`;
  }

  if (typeof props.paddingX === "number" && props.paddingX >= 0) {
    buttonStyle.paddingInline = `${props.paddingX}px`;
  }

  if (typeof props.paddingY === "number" && props.paddingY >= 0) {
    buttonStyle.paddingBlock = `${props.paddingY}px`;
  }

  return {
    wrapperWidthClass,
    buttonStyle,
  };
}
