/**
 * Element Factory
 *
 * Creates new canvas elements with proper defaults based on element type.
 * Uses the element registry for type-specific defaults.
 */

import { nanoid } from "nanoid";
import type {
  ElementType,
  CanvasElement,
  PriceElement,
  CurrencyElement,
  DiscountBadgeElement,
  TextElement,
  VariablePriceRangeElement,
  Position,
  TypographySettings,
  ResponsiveTypographySettings,
  ResponsiveBorderSettings,
  ResponsiveSpacing,
} from "../types";
import { createResponsiveValue, createDefaultResponsiveSpacing } from "../types";
import { getElementDefinition } from "./elementRegistry";

/**
 * Generate a unique element ID
 */
export function generateElementId(): string {
  return `el_${nanoid(8)}`;
}

/**
 * Calculate element size for a simple text/symbol (like currency symbols).
 * Uses canvas measureText for accurate measurement of any characters.
 */
export function calculateSymbolSize(
  symbol: string,
  typography: TypographySettings,
  padding: { top: number; right: number; bottom: number; left: number }
): { width: number; height: number } {
  const fontSize = typography.fontSize;

  // Create an offscreen canvas for measuring
  const canvas = document.createElement("canvas");
  const ctx = canvas.getContext("2d");

  let textWidth: number;

  if (ctx) {
    // Build font string
    const fontWeight = typography.fontWeight >= 700 ? "bold" : typography.fontWeight;
    const fontStyle = typography.fontStyle === "italic" ? "italic" : "";
    ctx.font = `${fontStyle} ${fontWeight} ${fontSize}px ${typography.fontFamily}`;

    // Measure the actual text width
    const metrics = ctx.measureText(symbol);
    const letterSpacingWidth = (symbol.length - 1) * typography.letterSpacing;
    textWidth = metrics.width + letterSpacingWidth;

    // Ensure minimum width based on character count and font size
    // This prevents extremely narrow elements at small font sizes
    const minWidth = symbol.length * fontSize * 0.5;
    textWidth = Math.max(textWidth, minWidth);
  } else {
    // Fallback estimation - some symbols like ﷼ or KSh are wider
    textWidth = fontSize * 0.8 * symbol.length;
  }

  // Add a small buffer to prevent clipping
  const widthBuffer = Math.max(2, fontSize * 0.1);

  return {
    width: Math.round(textWidth + padding.left + padding.right + widthBuffer),
    height: Math.round(fontSize + padding.top + padding.bottom),
  };
}

/**
 * Calculate badge size based on text content and typography
 * Uses canvas measureText for accurate measurement
 */
export function calculateBadgeSize(
  text: string,
  typography: TypographySettings,
  padding: { top: number; right: number; bottom: number; left: number }
): { width: number; height: number } {
  const fontSize = typography.fontSize;

  // Handle multiline text
  const lines = text.split("\n");
  const isMultiline = lines.length > 1;

  // Create an offscreen canvas for measuring
  const canvas = document.createElement("canvas");
  const ctx = canvas.getContext("2d");

  let textWidth: number;
  let textHeight: number;

  if (ctx) {
    // Build font string
    const fontWeight = typography.fontWeight >= 700 ? "bold" : typography.fontWeight;
    const fontStyle = typography.fontStyle === "italic" ? "italic" : "";
    ctx.font = `${fontStyle} ${fontWeight} ${fontSize}px ${typography.fontFamily}`;

    if (isMultiline) {
      // For multiline text, measure each line and use the max width
      let maxWidth = 0;
      for (const line of lines) {
        const metrics = ctx.measureText(line);
        const letterSpacingWidth = (line.length - 1) * typography.letterSpacing;
        const lineWidth = metrics.width + letterSpacingWidth;
        if (lineWidth > maxWidth) {
          maxWidth = lineWidth;
        }
      }
      textWidth = maxWidth;
      // Height = number of lines * fontSize * lineHeight
      textHeight = lines.length * fontSize * typography.lineHeight;
    } else {
      // Measure the actual text width
      const metrics = ctx.measureText(text);
      const letterSpacingWidth = (text.length - 1) * typography.letterSpacing;
      textWidth = metrics.width + letterSpacingWidth;
      textHeight = fontSize;
    }
  } else {
    // Fallback estimation
    if (isMultiline) {
      const maxLineLen = Math.max(...lines.map((l) => l.length));
      textWidth = maxLineLen * fontSize * 0.6;
      textHeight = lines.length * fontSize * typography.lineHeight;
    } else {
      textWidth = text.length * fontSize * 0.6;
      textHeight = fontSize;
    }
  }

  // Add a small buffer to prevent clipping
  const widthBuffer = Math.max(2, fontSize * 0.1);

  return {
    width: Math.round(textWidth + padding.left + padding.right + widthBuffer),
    height: Math.round(textHeight + padding.top + padding.bottom),
  };
}

/**
 * Calculate element size based on text content and typography
 * Matches the rendering logic in PriceElement.tsx
 *
 * For price elements with separate decimal:
 * - Height = mainFontSize + padding.top + padding.bottom (minimum to fit the main price)
 * - Width = currency + main + decimal widths + padding.left + padding.right
 */
export function calculateElementSize(
  text: string,
  typography: TypographySettings,
  padding: { top: number; right: number; bottom: number; left: number },
  showDecimals: boolean = true,
  decimalFontSize?: number,
  showCurrency: boolean = true
): { width: number; height: number } {
  const mainFontSize = typography.fontSize;
  const charWidth = mainFontSize * 0.6;

  // For price elements, calculate width matching the rendering layout
  const numericPart = text.replace(/^[^0-9]*/, "");
  const [mainPart, decimalPart] = numericPart.split(".");

  // Currency width (only if shown)
  const currencyWidth = showCurrency ? charWidth : 0;

  // Main price width
  const mainWidth = (mainPart?.length || 0) * charWidth;

  // Decimal width based on decimal font size (only if shown)
  let decimalWidth = 0;
  if (showDecimals && decimalPart) {
    const decCharWidth = decimalFontSize ? decimalFontSize * 0.6 : charWidth * 0.6;
    decimalWidth = (decimalPart.length + 1) * decCharWidth;
  }

  const textWidth = currencyWidth + mainWidth + decimalWidth;

  // Height is based on main font size (decimal fits within the main price height)
  const contentHeight = mainFontSize;

  return {
    width: Math.round(textWidth + padding.left + padding.right),
    height: Math.round(contentHeight + padding.top + padding.bottom),
  };
}

/**
 * Create a new canvas element of the specified type
 *
 * @param type - The element type to create
 * @param overrides - Optional property overrides
 * @param position - Optional position (defaults to registry defaults)
 */
export function createElement(type: ElementType, overrides?: Partial<CanvasElement>, position?: Position): CanvasElement {
  const definition = getElementDefinition(type);

  if (!definition) {
    throw new Error(`Unknown element type: ${type}`);
  }

  const id = generateElementId();
  const defaultProps = definition.defaultProps;

  // Merge position if provided
  const finalPosition = position ?? (defaultProps.position as Position);

  // Build base element
  const baseElement = {
    id,
    type,
    ...defaultProps,
    position: finalPosition,
    ...overrides,
  };

  // Type-specific element creation
  switch (type) {
    case "regularPrice":
    case "salePrice":
      return createPriceElement(baseElement as PriceElement);
    case "currencySymbol":
      return createCurrencyElement(baseElement as CurrencyElement);
    case "discountBadge":
      return createDiscountBadgeElement(baseElement as DiscountBadgeElement);
    case "text":
      return createTextElement(baseElement as TextElement);
    case "variablePriceRange":
      return createVariablePriceRangeElement(baseElement as VariablePriceRangeElement);
    default:
      return baseElement as CanvasElement;
  }
}

/**
 * Create a price element (regular or sale)
 */
function createPriceElement(
  props: Partial<PriceElement> & {
    id: string;
    type: "regularPrice" | "salePrice";
  }
): PriceElement {
  // Default responsive typography
  const defaultTypography: ResponsiveTypographySettings = {
    fontFamily: "Inter",
    fontSize: createResponsiveValue(24),
    fontWeight: createResponsiveValue(600),
    fontStyle: "normal",
    lineHeight: 1.2,
    letterSpacing: createResponsiveValue(0),
    textTransform: "none",
    textDecoration: "none",
  };
  const typography = props.typography ?? defaultTypography;

  // Default responsive padding
  const defaultPadding = createDefaultResponsiveSpacing(0);
  const padding = props.padding ?? defaultPadding;

  // Get decimal font size - handle both responsive and plain values
  const getDecimalFontSize = (): number => {
    const fontSize = props.decimal?.typography?.fontSize;
    if (fontSize === undefined) return 14;
    if (typeof fontSize === "object" && "desktop" in fontSize) {
      return fontSize.desktop;
    }
    return fontSize as number;
  };
  const decimalFontSize = getDecimalFontSize();
  const priceText = props.type === "regularPrice" ? "$99.99" : "$79.99";

  // Calculate size based on desktop typography values
  const typographyForCalc: TypographySettings = {
    fontFamily: typography.fontFamily,
    fontSize: typography.fontSize.desktop,
    fontWeight: typography.fontWeight.desktop,
    fontStyle: typography.fontStyle,
    lineHeight: typography.lineHeight,
    letterSpacing: typography.letterSpacing.desktop,
    textTransform: typography.textTransform,
    textDecoration: typography.textDecoration,
  };
  const paddingForCalc = {
    top: padding.top.desktop,
    right: padding.right.desktop,
    bottom: padding.bottom.desktop,
    left: padding.left.desktop,
  };
  const calculatedSize = calculateElementSize(priceText, typographyForCalc, paddingForCalc, true, decimalFontSize);

  // Default responsive border
  const defaultBorder: ResponsiveBorderSettings = {
    width: createResponsiveValue(0),
    style: "solid",
    color: "#000000",
    radius: 0,
  };

  return {
    id: props.id,
    type: props.type,
    name: props.name ?? "Price",
    position: props.position ?? { x: 100, y: 100 },
    size: props.size ?? calculatedSize,
    rotation: props.rotation ?? 0,
    zIndex: props.zIndex ?? 1,
    visible: props.visible ?? true,
    locked: props.locked ?? false,
    color: props.color ?? "#374151",
    backgroundColor: props.backgroundColor ?? "transparent",
    opacity: props.opacity ?? 1,
    typography,
    border: props.border ?? defaultBorder,
    padding,
    margin: props.margin ?? createDefaultResponsiveSpacing(0),
    positionType: props.positionType ?? "relative",
    animation: props.animation ?? {
      type: "none",
      duration: 300,
      delay: 0,
      easing: "ease-out",
    },
    decimal: props.decimal ?? {
      show: true,
      showCurrency: true,
      separator: "point",
      typography: { fontSize: createResponsiveValue(decimalFontSize) },
      position: "superscript",
    },
    lineThrough: props.lineThrough,
  };
}

/**
 * Create a currency symbol element
 */
function createCurrencyElement(props: Partial<CurrencyElement> & { id: string; type: "currencySymbol" }): CurrencyElement {
  // Get WooCommerce currency as default
  const wcCurrency = window.oppbAdmin?.currency;
  const defaultSymbol = wcCurrency?.symbol ?? "$";
  const defaultCode = wcCurrency?.code ?? "USD";

  // Default responsive typography
  const defaultTypography: ResponsiveTypographySettings = {
    fontFamily: "Inter",
    fontSize: createResponsiveValue(18),
    fontWeight: createResponsiveValue(600),
    fontStyle: "normal",
    lineHeight: 1.2,
    letterSpacing: createResponsiveValue(0),
    textTransform: "none",
    textDecoration: "none",
  };
  const typography = props.typography ?? defaultTypography;

  // Default responsive padding
  const defaultPadding = createDefaultResponsiveSpacing(0);
  const padding = props.padding ?? defaultPadding;

  // Calculate size based on the symbol using desktop values
  const symbol = props.symbol ?? defaultSymbol;
  const typographyForCalc: TypographySettings = {
    fontFamily: typography.fontFamily,
    fontSize: typography.fontSize.desktop,
    fontWeight: typography.fontWeight.desktop,
    fontStyle: typography.fontStyle,
    lineHeight: typography.lineHeight,
    letterSpacing: typography.letterSpacing.desktop,
    textTransform: typography.textTransform,
    textDecoration: typography.textDecoration,
  };
  const paddingForCalc = {
    top: padding.top.desktop,
    right: padding.right.desktop,
    bottom: padding.bottom.desktop,
    left: padding.left.desktop,
  };
  // Use calculateSymbolSize for currency symbols (not price-specific calculation)
  const calculatedSize = calculateSymbolSize(symbol, typographyForCalc, paddingForCalc);

  // Default responsive border
  const defaultBorder: ResponsiveBorderSettings = {
    width: createResponsiveValue(0),
    style: "solid",
    color: "#000000",
    radius: 0,
  };

  return {
    id: props.id,
    type: props.type,
    name: props.name ?? "Currency",
    position: props.position ?? { x: 70, y: 100 },
    size: props.size ?? calculatedSize,
    rotation: props.rotation ?? 0,
    zIndex: props.zIndex ?? 1,
    visible: props.visible ?? true,
    locked: props.locked ?? false,
    color: props.color ?? "#374151",
    backgroundColor: props.backgroundColor ?? "transparent",
    opacity: props.opacity ?? 1,
    typography,
    border: props.border ?? defaultBorder,
    padding,
    margin: props.margin ?? createDefaultResponsiveSpacing(0),
    positionType: props.positionType ?? "relative",
    animation: props.animation ?? {
      type: "none",
      duration: 300,
      delay: 0,
      easing: "ease-out",
    },
    symbol: props.symbol ?? defaultSymbol,
    symbolCode: props.symbolCode ?? defaultCode,
    useCustomImage: props.useCustomImage ?? false,
    customImageUrl: props.customImageUrl ?? null,
    customImageId: props.customImageId ?? null,
    useCustomSvg: props.useCustomSvg ?? false,
    customSvg: props.customSvg ?? null,
    symbolPosition: props.symbolPosition ?? "before",
  };
}

/**
 * Create a discount badge element
 */
function createDiscountBadgeElement(props: Partial<DiscountBadgeElement> & { id: string; type: "discountBadge" }): DiscountBadgeElement {
  // Default responsive typography
  const defaultTypography: ResponsiveTypographySettings = {
    fontFamily: "Inter",
    fontSize: createResponsiveValue(14),
    fontWeight: createResponsiveValue(700),
    fontStyle: "normal",
    lineHeight: 1.2,
    letterSpacing: createResponsiveValue(0),
    textTransform: "none",
    textDecoration: "none",
  };
  const typography = props.typography ?? defaultTypography;

  // Default responsive padding
  const defaultPadding: ResponsiveSpacing = {
    top: createResponsiveValue(4),
    right: createResponsiveValue(8),
    bottom: createResponsiveValue(4),
    left: createResponsiveValue(8),
  };
  const padding = props.padding ?? defaultPadding;

  // Calculate size based on desktop typography values
  const typographyForCalc: TypographySettings = {
    fontFamily: typography.fontFamily,
    fontSize: typography.fontSize.desktop,
    fontWeight: typography.fontWeight.desktop,
    fontStyle: typography.fontStyle,
    lineHeight: typography.lineHeight,
    letterSpacing: typography.letterSpacing.desktop,
    textTransform: typography.textTransform,
    textDecoration: typography.textDecoration,
  };
  const paddingForCalc = {
    top: padding.top.desktop,
    right: padding.right.desktop,
    bottom: padding.bottom.desktop,
    left: padding.left.desktop,
  };

  // Use the format and customFormat from props to calculate proper size
  const format = props.format ?? "percentage";
  const customFormat = props.customFormat ?? "-{discount}%";
  let displayText: string;
  if (format === "amount") {
    displayText = "-$19.99";
  } else if (format === "custom" && customFormat) {
    // Replace placeholders with sample values for proper sizing
    displayText = customFormat
      .replace("{discount}", "20")
      .replace("{discountPercentage}", "20")
      .replace("{discountAmount}", "$19.99")
      .replace("{discountAmountRaw}", "19.99");
  } else {
    displayText = "-20%";
  }
  const calculatedSize = calculateBadgeSize(displayText, typographyForCalc, paddingForCalc);

  // Default responsive border
  const defaultBorder: ResponsiveBorderSettings = {
    width: createResponsiveValue(0),
    style: "solid",
    color: "#000000",
    radius: 4,
  };

  return {
    id: props.id,
    type: props.type,
    name: props.name ?? "Discount",
    position: props.position ?? { x: 200, y: 80 },
    size: props.size ?? calculatedSize,
    rotation: props.rotation ?? 0,
    zIndex: props.zIndex ?? 3,
    visible: props.visible ?? true,
    locked: props.locked ?? false,
    color: props.color ?? "#ffffff",
    backgroundColor: props.backgroundColor ?? "#dc2626",
    opacity: props.opacity ?? 1,
    typography,
    border: props.border ?? defaultBorder,
    padding,
    margin: props.margin ?? createDefaultResponsiveSpacing(0),
    positionType: props.positionType ?? "relative",
    animation: props.animation ?? {
      type: "scaleIn",
      duration: 300,
      delay: 0,
      easing: "ease-out",
    },
    format: props.format ?? "percentage",
    customFormat: props.customFormat ?? "-{discount}%",
  };
}

/**
 * Create a text element
 */
function createTextElement(props: Partial<TextElement> & { id: string; type: "text" }): TextElement {
  // Default responsive typography
  const defaultTypography: ResponsiveTypographySettings = {
    fontFamily: "Inter",
    fontSize: createResponsiveValue(16),
    fontWeight: createResponsiveValue(400),
    fontStyle: "normal",
    lineHeight: 1.2,
    letterSpacing: createResponsiveValue(0),
    textTransform: "none",
    textDecoration: "none",
  };
  const typography = props.typography ?? defaultTypography;

  // Default responsive padding
  const defaultPadding = createDefaultResponsiveSpacing(0);
  const padding = props.padding ?? defaultPadding;
  const text = props.text ?? "Your text here";

  // Calculate size based on desktop typography values
  const typographyForCalc: TypographySettings = {
    fontFamily: typography.fontFamily,
    fontSize: typography.fontSize.desktop,
    fontWeight: typography.fontWeight.desktop,
    fontStyle: typography.fontStyle,
    lineHeight: typography.lineHeight,
    letterSpacing: typography.letterSpacing.desktop,
    textTransform: typography.textTransform,
    textDecoration: typography.textDecoration,
  };
  const paddingForCalc = {
    top: padding.top.desktop,
    right: padding.right.desktop,
    bottom: padding.bottom.desktop,
    left: padding.left.desktop,
  };
  // Use calculateSymbolSize for text elements - it uses canvas measureText for accurate sizing
  const calculatedSize = calculateSymbolSize(text, typographyForCalc, paddingForCalc);

  // Default responsive border
  const defaultBorder: ResponsiveBorderSettings = {
    width: createResponsiveValue(0),
    style: "solid",
    color: "#000000",
    radius: 0,
  };

  return {
    id: props.id,
    type: props.type,
    name: props.name ?? "Text",
    position: props.position ?? { x: 100, y: 100 },
    size: props.size ?? calculatedSize,
    rotation: props.rotation ?? 0,
    zIndex: props.zIndex ?? 1,
    visible: props.visible ?? true,
    locked: props.locked ?? false,
    color: props.color ?? "#374151",
    backgroundColor: props.backgroundColor ?? "transparent",
    opacity: props.opacity ?? 1,
    typography,
    border: props.border ?? defaultBorder,
    padding,
    margin: props.margin ?? createDefaultResponsiveSpacing(0),
    positionType: props.positionType ?? "relative",
    animation: props.animation ?? {
      type: "none",
      duration: 300,
      delay: 0,
      easing: "ease-out",
    },
    text,
    textAlign: props.textAlign ?? "left",
    verticalAlign: props.verticalAlign ?? "top",
    widthMode: props.widthMode ?? "auto",
    customWidth: props.customWidth ?? 200,
    backgroundImage: props.backgroundImage ?? null,
    backgroundImageId: props.backgroundImageId ?? null,
    backgroundSize: props.backgroundSize ?? "cover",
    backgroundPosition: props.backgroundPosition ?? "center",
    backgroundRepeat: props.backgroundRepeat ?? "no-repeat",
  };
}

/**
 * Create a variable price range element
 */
function createVariablePriceRangeElement(
  props: Partial<VariablePriceRangeElement> & {
    id: string;
    type: "variablePriceRange";
  }
): VariablePriceRangeElement {
  // Default responsive typography
  const defaultTypography: ResponsiveTypographySettings = {
    fontFamily: "Inter",
    fontSize: createResponsiveValue(24),
    fontWeight: createResponsiveValue(600),
    fontStyle: "normal",
    lineHeight: 1.2,
    letterSpacing: createResponsiveValue(0),
    textTransform: "none",
    textDecoration: "none",
  };
  const typography = props.typography ?? defaultTypography;

  // Default responsive padding
  const defaultPadding = createDefaultResponsiveSpacing(0);
  const padding = props.padding ?? defaultPadding;

  // Get display mode
  const displayMode = props.displayMode ?? "range";
  const showCurrency = props.showCurrency ?? true;
  const separator = props.separator ?? " – ";
  const prefixText = props.prefixText ?? (displayMode === "up-to" ? "Up to" : "From");

  // Main font size for calculations
  const mainFontSize = typography.fontSize.desktop;

  // Min/max font sizes - inherit from main if not explicitly set
  const minFontSize = props.minPriceTypography?.fontSize?.desktop ?? mainFontSize;
  const maxFontSize = props.maxPriceTypography?.fontSize?.desktop ?? mainFontSize;
  const separatorFontSize = props.separatorTypography?.fontSize?.desktop ?? Math.round(mainFontSize * 0.75);

  // Decimal font sizes - scale proportionally (don't use fixed values)
  const minDecimalSize = props.minDecimal?.typography?.fontSize?.desktop ?? Math.round(minFontSize * 0.6);
  const maxDecimalSize = props.maxDecimal?.typography?.fontSize?.desktop ?? Math.round(maxFontSize * 0.6);

  // Calculate proper width based on actual rendering
  const paddingH = padding.left.desktop + padding.right.desktop;

  // Helper to calculate single price width
  const calcPriceWidth = (fontSize: number, decFontSize: number): number => {
    const charWidth = fontSize * 0.6;
    const decCharWidth = decFontSize * 0.6;
    // Currency + "99" main + ".99" decimal
    const currencyWidth = showCurrency ? charWidth : 0;
    const mainWidth = 2 * charWidth; // "99" or "19"
    const decimalWidth = 3 * decCharWidth; // ".99"
    return currencyWidth + mainWidth + decimalWidth;
  };

  let calculatedWidth: number;
  switch (displayMode) {
    case "from": {
      const prefixWidth = prefixText.length * separatorFontSize * 0.6;
      const priceWidth = calcPriceWidth(minFontSize, minDecimalSize);
      calculatedWidth = prefixWidth + 8 + priceWidth + paddingH;
      break;
    }
    case "up-to": {
      const prefixWidth = prefixText.length * separatorFontSize * 0.6;
      const priceWidth = calcPriceWidth(maxFontSize, maxDecimalSize);
      calculatedWidth = prefixWidth + 8 + priceWidth + paddingH;
      break;
    }
    case "min-only": {
      calculatedWidth = calcPriceWidth(minFontSize, minDecimalSize) + paddingH;
      break;
    }
    case "max-only": {
      calculatedWidth = calcPriceWidth(maxFontSize, maxDecimalSize) + paddingH;
      break;
    }
    case "range":
    default: {
      const minWidth = calcPriceWidth(minFontSize, minDecimalSize);
      const sepWidth = separator.length * separatorFontSize * 0.6;
      const maxWidth = calcPriceWidth(maxFontSize, maxDecimalSize);
      calculatedWidth = minWidth + sepWidth + maxWidth + paddingH;
      break;
    }
  }

  // Height based on largest font used
  const maxUsedFontSize = Math.max(minFontSize, maxFontSize, separatorFontSize);
  const calculatedHeight = maxUsedFontSize + padding.top.desktop + padding.bottom.desktop;

  const calculatedSize = {
    width: Math.ceil(calculatedWidth),
    height: Math.ceil(calculatedHeight),
  };

  // Default responsive border
  const defaultBorder: ResponsiveBorderSettings = {
    width: createResponsiveValue(0),
    style: "solid",
    color: "#000000",
    radius: 0,
  };

  return {
    id: props.id,
    type: props.type,
    name: props.name ?? "Price Range",
    position: props.position ?? { x: 100, y: 100 },
    size: props.size ?? calculatedSize,
    rotation: props.rotation ?? 0,
    zIndex: props.zIndex ?? 1,
    visible: props.visible ?? true,
    locked: props.locked ?? false,
    color: props.color ?? "#374151",
    backgroundColor: props.backgroundColor ?? "transparent",
    opacity: props.opacity ?? 1,
    typography,
    border: props.border ?? defaultBorder,
    padding,
    margin: props.margin ?? createDefaultResponsiveSpacing(0),
    positionType: props.positionType ?? "relative",
    animation: props.animation ?? {
      type: "none",
      duration: 300,
      delay: 0,
      easing: "ease-out",
    },
    displayMode,
    separator,
    prefixText,
    showCurrency,
    // Typography for separator/prefix - undefined means inherit from main typography
    separatorTypography: props.separatorTypography,
    // Typography for min/max prices - undefined means inherit from main typography
    minPriceTypography: props.minPriceTypography,
    maxPriceTypography: props.maxPriceTypography,
    // Decimal settings - DON'T set fixed fontSize, let renderer calculate proportionally
    minDecimal: props.minDecimal ?? {
      show: true,
      showCurrency: true,
      separator: "point",
      typography: {}, // Empty - will inherit proportionally from price font size
      position: "superscript",
    },
    maxDecimal: props.maxDecimal ?? {
      show: true,
      showCurrency: true,
      separator: "point",
      typography: {}, // Empty - will inherit proportionally from price font size
      position: "superscript",
    },
    showOriginalRange: props.showOriginalRange ?? false,
    lineThrough: props.lineThrough,
  };
}

/**
 * Duplicate an existing element with a new ID
 */
export function duplicateElement(element: CanvasElement, offset: Position = { x: 20, y: 20 }): CanvasElement {
  return {
    ...element,
    id: generateElementId(),
    name: `${element.name} (copy)`,
    position: {
      x: element.position.x + offset.x,
      y: element.position.y + offset.y,
    },
  };
}

/**
 * Get display label for an element
 */
export function getElementLabel(element: CanvasElement): string {
  const definition = getElementDefinition(element.type);
  return definition?.label ?? element.type;
}

/**
 * Get icon name for an element
 */
export function getElementIcon(element: CanvasElement): string {
  const definition = getElementDefinition(element.type);
  return definition?.icon ?? "Box";
}
