/**
 * CSS Generator Functions for Layout Exporter
 *
 * Generates CSS rules from canvas elements for price display layouts.
 */

import type { CanvasElement, PriceElement, VariablePriceRangeElement } from "@/types";
import { DEFAULT_FONT_VALUE, getFontCssValue } from "@/types";
import type { ContainerBounds } from "../layoutAnalyzer";
import { getClassName, getDesktopValue, generateTypographyCSS } from "./utils";

/**
 * Generate base CSS for an element (without positioning)
 */
export function generateBaseElementCSS(el: CanvasElement): string {
  const rules: string[] = [];

  // Colors
  rules.push(`color: ${el.color}`);
  if (el.backgroundColor !== "transparent") {
    rules.push(`background-color: ${el.backgroundColor}`);
  }

  // Opacity
  if (el.opacity < 1) {
    rules.push(`opacity: ${el.opacity}`);
  }

  // Typography
  rules.push(generateTypographyCSS(el));

  // Border
  if (el.border.width.desktop > 0) {
    rules.push(`border: ${el.border.width.desktop}px ${el.border.style} ${el.border.color}`);
  }
  if (el.border.radius > 0) {
    rules.push(`border-radius: ${el.border.radius}px`);
  }

  // Padding
  if (el.padding.top.desktop > 0 || el.padding.right.desktop > 0 || el.padding.bottom.desktop > 0 || el.padding.left.desktop > 0) {
    rules.push(
      `padding: ${el.padding.top.desktop}px ${el.padding.right.desktop}px ${el.padding.bottom.desktop}px ${el.padding.left.desktop}px`
    );
  }

  // Margin
  if (el.margin.top.desktop > 0 || el.margin.right.desktop > 0 || el.margin.bottom.desktop > 0 || el.margin.left.desktop > 0) {
    rules.push(`margin: ${el.margin.top.desktop}px ${el.margin.right.desktop}px ${el.margin.bottom.desktop}px ${el.margin.left.desktop}px`);
  }

  // Rotation
  if (el.rotation !== 0) {
    rules.push(`transform: rotate(${el.rotation}deg)`);
  }

  return rules.join(";\n  ");
}

/**
 * Generate CSS for absolute positioned element
 */
export function generateAbsoluteCSS(el: CanvasElement, containerBounds: ContainerBounds): string {
  const rules: string[] = [];

  rules.push("position: absolute");

  const relativeX = Math.round(el.position.x - containerBounds.x);
  const relativeY = Math.round(el.position.y - containerBounds.y);

  rules.push(`left: ${relativeX}px`);
  rules.push(`top: ${relativeY}px`);

  return rules.join(";\n  ");
}

/**
 * Generate decimal CSS if needed
 */
export function generateDecimalCSS(el: PriceElement): string {
  if (!el.decimal?.show || el.decimal.position === "inline") return "";

  const className = getClassName(el.type);
  const decimalTypo = el.decimal.typography || {};
  const rules: string[] = [];

  const hasExplicitFontSize = decimalTypo.fontSize?.desktop !== undefined;
  const decimalFontSize = hasExplicitFontSize ? decimalTypo.fontSize!.desktop : Math.round(el.typography.fontSize.desktop * 0.6);

  if (el.decimal.position === "top") {
    rules.push("vertical-align: top");
    rules.push(`font-size: ${decimalFontSize}px`);
  } else if (el.decimal.position === "superscript") {
    rules.push("vertical-align: super");
    rules.push(`font-size: ${decimalFontSize}px`);
  } else if (el.decimal.position === "baseline") {
    rules.push("vertical-align: baseline");
    rules.push(`font-size: ${decimalFontSize}px`);
  } else if (el.decimal.position === "absolute") {
    rules.push("position: absolute");
    if (el.decimal.absoluteOffset) {
      rules.push(`left: ${el.decimal.absoluteOffset.x}px`);
      rules.push(`top: ${el.decimal.absoluteOffset.y}px`);
    }
    rules.push(`font-size: ${decimalFontSize}px`);
  }

  const fontWeight = getDesktopValue(decimalTypo.fontWeight, undefined);
  if (fontWeight) {
    rules.push(`font-weight: ${fontWeight}`);
  }
  if (decimalTypo.fontFamily && decimalTypo.fontFamily !== DEFAULT_FONT_VALUE) {
    const decimalFontCss = getFontCssValue(decimalTypo.fontFamily);
    if (decimalFontCss) {
      rules.push(`font-family: ${decimalFontCss}`);
    }
  }
  const fontStyle = decimalTypo.fontStyle ?? "normal";
  rules.push(`font-style: ${fontStyle}`);
  rules.push("white-space: nowrap");
  const letterSpacing = getDesktopValue(decimalTypo.letterSpacing, 0);
  if (letterSpacing !== 0) {
    rules.push(`letter-spacing: ${letterSpacing}px`);
  }
  const textDecoration = decimalTypo.textDecoration ?? "none";
  if (textDecoration !== "none") {
    rules.push(`text-decoration: ${textDecoration}`);
  }

  return `.${className}__decimal {
  ${rules.join(";\n  ")};
}`;
}

/**
 * Generate line-through CSS if needed
 */
export function generateLineThroughCSS(el: PriceElement): string {
  if (!el.lineThrough?.enabled) return "";

  const className = getClassName(el.type);
  const lt = el.lineThrough;

  const positionRule = el.positionType === "absolute" ? "" : "position: relative;";

  if (lt.style === "cross") {
    return `.${className}::before,
.${className}::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: ${lt.thickness}px;
  background-color: ${lt.color};
}

.${className}::before {
  transform: translateY(-50%) rotate(15deg);
}

.${className}::after {
  transform: translateY(-50%) rotate(-15deg);
}
${
  positionRule
    ? `
.${className} {
  ${positionRule}
}`
    : ""
}`;
  }

  let rotation = 0;
  if (lt.direction === "diagonal-down") {
    rotation = 15;
  } else if (lt.direction === "diagonal-up") {
    rotation = -15;
  }

  return `.${className}::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: ${lt.thickness}px;
  background-color: ${lt.color};
  transform: translateY(-50%)${rotation !== 0 ? ` rotate(${rotation}deg)` : ""};
  ${lt.style === "double" ? `box-shadow: 0 ${lt.thickness + 2}px 0 ${lt.color};` : ""}
}
${
  positionRule
    ? `
.${className} {
  ${positionRule}
}`
    : ""
}`;
}

/**
 * Generate CSS for variable price range element
 */
export function generateVariablePriceRangeCSS(el: VariablePriceRangeElement): string {
  const className = "oppb-variable-range";
  const rules: string[] = [];

  const mainFontSize = el.typography.fontSize.desktop;
  const mainFontWeight = el.typography.fontWeight.desktop;

  const hasSeparatorFontSize = el.separatorTypography?.fontSize !== undefined;
  const hasSeparatorFontWeight = el.separatorTypography?.fontWeight !== undefined;
  const hasMinFontSize = el.minPriceTypography?.fontSize !== undefined;
  const hasMinFontWeight = el.minPriceTypography?.fontWeight !== undefined;
  const hasMaxFontSize = el.maxPriceTypography?.fontSize !== undefined;
  const hasMaxFontWeight = el.maxPriceTypography?.fontWeight !== undefined;

  const sepFontSize = hasSeparatorFontSize ? getDesktopValue(el.separatorTypography!.fontSize, mainFontSize * 0.75) : mainFontSize * 0.75;
  const sepFontWeight = hasSeparatorFontWeight ? getDesktopValue(el.separatorTypography!.fontWeight, mainFontWeight) : mainFontWeight;
  const sepLetterSpacing = getDesktopValue(el.separatorTypography?.letterSpacing, 4);
  rules.push(`.${className}__separator {
  font-size: ${sepFontSize}px;
  font-weight: ${sepFontWeight};
  padding: 0 ${sepLetterSpacing}px;
}`);

  rules.push(`.${className}__prefix {
  font-size: ${sepFontSize}px;
  font-weight: ${sepFontWeight};
  margin-right: 4px;
}`);

  const minFontSize = hasMinFontSize ? getDesktopValue(el.minPriceTypography!.fontSize, mainFontSize) : mainFontSize;
  const minFontWeight = hasMinFontWeight ? getDesktopValue(el.minPriceTypography!.fontWeight, mainFontWeight) : mainFontWeight;
  rules.push(`.${className}__min {
  font-size: ${minFontSize}px;
  font-weight: ${minFontWeight};
}`);

  rules.push(`.${className}__min-currency,
.${className}__min-main {
  font-size: inherit;
  font-weight: inherit;
}`);

  const maxFontSize = hasMaxFontSize ? getDesktopValue(el.maxPriceTypography!.fontSize, mainFontSize) : mainFontSize;
  const maxFontWeight = hasMaxFontWeight ? getDesktopValue(el.maxPriceTypography!.fontWeight, mainFontWeight) : mainFontWeight;
  rules.push(`.${className}__max {
  font-size: ${maxFontSize}px;
  font-weight: ${maxFontWeight};
}`);

  rules.push(`.${className}__max-currency,
.${className}__max-main {
  font-size: inherit;
  font-weight: inherit;
}`);

  // Min price decimal
  if (el.minDecimal?.show && el.minDecimal.position !== "inline") {
    const decTypo = el.minDecimal.typography || {};
    const position = el.minDecimal.position;
    const decRules: string[] = [];

    if (position === "top") {
      decRules.push("vertical-align: top");
    } else if (position === "superscript") {
      decRules.push("vertical-align: super");
    } else if (position === "baseline") {
      decRules.push("vertical-align: baseline");
    }

    const hasMinDecFontSize = decTypo.fontSize?.desktop !== undefined;
    const minDecFontSize = hasMinDecFontSize ? decTypo.fontSize!.desktop : Math.round(minFontSize * 0.6);
    const minDecFontWeight = getDesktopValue(decTypo.fontWeight, undefined);
    decRules.push(`font-size: ${minDecFontSize}px`);
    if (minDecFontWeight) decRules.push(`font-weight: ${minDecFontWeight}`);
    const minDecFontStyle = decTypo.fontStyle ?? "normal";
    decRules.push(`font-style: ${minDecFontStyle}`);
    const minDecLetterSpacing = getDesktopValue(decTypo.letterSpacing, 0);
    if (minDecLetterSpacing !== 0) decRules.push(`letter-spacing: ${minDecLetterSpacing}px`);
    const minDecTextDecoration = decTypo.textDecoration ?? "none";
    if (minDecTextDecoration !== "none") decRules.push(`text-decoration: ${minDecTextDecoration}`);

    rules.push(`.${className}__min-decimal {
  ${decRules.join(";\n  ")};
}`);
  }

  // Max price decimal
  if (el.maxDecimal?.show && el.maxDecimal.position !== "inline") {
    const decTypo = el.maxDecimal.typography || {};
    const position = el.maxDecimal.position;
    const decRules: string[] = [];

    if (position === "top") {
      decRules.push("vertical-align: top");
    } else if (position === "superscript") {
      decRules.push("vertical-align: super");
    } else if (position === "baseline") {
      decRules.push("vertical-align: baseline");
    }

    const hasMaxDecFontSize = decTypo.fontSize?.desktop !== undefined;
    const maxDecFontSize = hasMaxDecFontSize ? decTypo.fontSize!.desktop : Math.round(maxFontSize * 0.6);
    const maxDecFontWeight = getDesktopValue(decTypo.fontWeight, undefined);
    decRules.push(`font-size: ${maxDecFontSize}px`);
    if (maxDecFontWeight) decRules.push(`font-weight: ${maxDecFontWeight}`);
    const maxDecFontStyle = decTypo.fontStyle ?? "normal";
    decRules.push(`font-style: ${maxDecFontStyle}`);
    const maxDecLetterSpacing = getDesktopValue(decTypo.letterSpacing, 0);
    if (maxDecLetterSpacing !== 0) decRules.push(`letter-spacing: ${maxDecLetterSpacing}px`);
    const maxDecTextDecoration = decTypo.textDecoration ?? "none";
    if (maxDecTextDecoration !== "none") decRules.push(`text-decoration: ${maxDecTextDecoration}`);

    rules.push(`.${className}__max-decimal {
  ${decRules.join(";\n  ")};
}`);
  }

  // Line-through for max price
  if (el.lineThrough?.enabled) {
    const lt = el.lineThrough;
    rules.push(`.${className}__max {
  position: relative;
}

.${className}__max::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: ${lt.thickness || 2}px;
  background-color: ${lt.color || "#000"};
  transform: translateY(-50%);
}`);
  }

  return rules.join("\n\n");
}

/**
 * Generate discount badge specific CSS
 */
export function generateDiscountBadgeCSS(el: CanvasElement): string {
  const rules: string[] = [];
  const className = "oppb-discount-badge";

  // Add flexbox for multiline support
  const discountEl = el as CanvasElement & { format?: string; customFormat?: string };
  const hasMultiline = discountEl.format === "custom" && discountEl.customFormat && discountEl.customFormat.includes("\n");

  if (hasMultiline) {
    rules.push(`
.${className} {
  display: inline-flex;
  flex-direction: column;
  text-align: center;
  justify-content: center;
  align-items: center;
}

.oppb-discount-line {
  display: block;
}`);
  }

  return rules.join("\n");
}

/**
 * Generate text element specific CSS
 */
export function generateTextElementCSS(el: CanvasElement): string {
  const textEl = el as CanvasElement & { text?: string };
  const hasMultiline = textEl.text && textEl.text.includes("\n");

  if (!hasMultiline) return "";

  return `
.oppb-text {
  display: inline-flex;
  flex-direction: column;
}

.oppb-text-line {
  display: block;
}`;
}
