/**
 * HTML Generator Functions for Layout Exporter
 *
 * Generates semantic HTML from canvas elements for price display layouts.
 */

import type { CanvasElement, PriceElement, CurrencyElement, DiscountBadgeElement, TextElement, VariablePriceRangeElement } from "@/types";
import { getClassName, escapeHtml } from "./utils";
import { isPriceElement, isVariablePriceRangeElement, isCurrencyElement, isDiscountBadgeElement, isTextElement } from "./types";

/**
 * Generate HTML for a price element
 */
export function generatePriceHTML(el: PriceElement, useWebComponent: boolean): string {
  const className = getClassName(el.type);
  const placeholder = el.type === "regularPrice" ? "{regularPrice}" : "{salePrice}";
  const mainPlaceholder = el.type === "regularPrice" ? "{regularPriceMain}" : "{salePriceMain}";
  const decimalPlaceholder = el.type === "regularPrice" ? "{regularPriceDecimal}" : "{salePriceDecimal}";

  // Get separator character - hardcoded in HTML since it's a design choice, not runtime data
  let separator = ".";
  if (el.decimal?.separator === "comma") {
    separator = ",";
  } else if (el.decimal?.separator === "none") {
    separator = "";
  }

  // Check if currency should be shown (default true)
  const showCurrency = el.decimal?.showCurrency ?? true;
  const currencyHtml = showCurrency
    ? useWebComponent
      ? `<span class="${className}__currency">{currencySymbol}</span>`
      : `<span class="${className}__currency">$</span>`
    : "";

  // Generate structured price HTML
  if (el.decimal?.show && el.decimal.position !== "inline") {
    if (useWebComponent) {
      return `<span class="${className}">${currencyHtml}<span class="${className}__main">${mainPlaceholder}</span><span class="${className}__decimal">${separator}${decimalPlaceholder}</span></span>`;
    }
    return `<span class="${className}">${currencyHtml}<span class="${className}__main">99</span><span class="${className}__decimal">${separator}99</span></span>`;
  }

  if (useWebComponent) {
    if (el.decimal?.show === false) {
      return showCurrency
        ? `<span class="${className}">{currencySymbol}${mainPlaceholder}</span>`
        : `<span class="${className}">${mainPlaceholder}</span>`;
    }
    return showCurrency
      ? `<span class="${className}">${placeholder}</span>`
      : `<span class="${className}">${mainPlaceholder}${separator}${decimalPlaceholder}</span>`;
  }

  if (el.decimal?.show === false) {
    return showCurrency ? `<span class="${className}">$99</span>` : `<span class="${className}">99</span>`;
  }
  return showCurrency ? `<span class="${className}">$99.99</span>` : `<span class="${className}">99${separator}99</span>`;
}

/**
 * Generate HTML for a variable price range element
 */
export function generateVariablePriceRangeHTML(el: VariablePriceRangeElement, useWebComponent: boolean): string {
  const className = "oppb-variable-range";
  const displayMode = el.displayMode || "range";
  const separator = el.separator || " – ";
  const prefixText = el.prefixText || "From ";
  const showCurrency = el.showCurrency ?? true;

  const getDecimalSeparator = (decimalSettings: VariablePriceRangeElement["minDecimal"]): string => {
    if (!decimalSettings?.separator || decimalSettings.separator === "point") {
      return ".";
    }
    if (decimalSettings.separator === "comma") {
      return ",";
    }
    return "";
  };

  const minSeparator = getDecimalSeparator(el.minDecimal);
  const maxSeparator = getDecimalSeparator(el.maxDecimal);

  const getMinPriceHTML = (withDecimal: boolean): string => {
    if (withDecimal && el.minDecimal?.show && el.minDecimal.position !== "inline") {
      if (useWebComponent) {
        const currencySpan = showCurrency ? `<span class="${className}__min-currency">{currencySymbol}</span>` : "";
        return `${currencySpan}<span class="${className}__min-main">{minPriceMain}</span><span class="${className}__min-decimal">${minSeparator}{minPriceDecimal}</span>`;
      }
      const currencySpan = showCurrency ? `<span class="${className}__min-currency">$</span>` : "";
      return `${currencySpan}<span class="${className}__min-main">19</span><span class="${className}__min-decimal">${minSeparator}99</span>`;
    }
    if (useWebComponent) {
      if (el.minDecimal?.show === false) {
        return showCurrency ? `{currencySymbol}{minPriceMain}` : `{minPriceMain}`;
      }
      return showCurrency ? `{minPrice}` : `{minPriceMain}`;
    }
    return showCurrency ? `$19` : `19`;
  };

  const getMaxPriceHTML = (withDecimal: boolean): string => {
    if (withDecimal && el.maxDecimal?.show && el.maxDecimal.position !== "inline") {
      if (useWebComponent) {
        const currencySpan = showCurrency ? `<span class="${className}__max-currency">{currencySymbol}</span>` : "";
        return `${currencySpan}<span class="${className}__max-main">{maxPriceMain}</span><span class="${className}__max-decimal">${maxSeparator}{maxPriceDecimal}</span>`;
      }
      const currencySpan = showCurrency ? `<span class="${className}__max-currency">$</span>` : "";
      return `${currencySpan}<span class="${className}__max-main">99</span><span class="${className}__max-decimal">${maxSeparator}99</span>`;
    }
    if (useWebComponent) {
      if (el.maxDecimal?.show === false) {
        return showCurrency ? `{currencySymbol}{maxPriceMain}` : `{maxPriceMain}`;
      }
      return showCurrency ? `{maxPrice}` : `{maxPriceMain}`;
    }
    return showCurrency ? `$99` : `99`;
  };

  const minHasDecimal = el.minDecimal?.show && el.minDecimal.position !== "inline";
  const maxHasDecimal = el.maxDecimal?.show && el.maxDecimal.position !== "inline";

  let innerHtml = "";
  switch (displayMode) {
    case "range":
      innerHtml = `<span class="${className}__min">${getMinPriceHTML(
        !!minHasDecimal
      )}</span><span class="${className}__separator">${separator}</span><span class="${className}__max">${getMaxPriceHTML(
        !!maxHasDecimal
      )}</span>`;
      break;
    case "from":
      innerHtml = `<span class="${className}__prefix">${prefixText}</span><span class="${className}__min">${getMinPriceHTML(
        !!minHasDecimal
      )}</span>`;
      break;
    case "up-to":
      innerHtml = `<span class="${className}__prefix">${prefixText}</span><span class="${className}__max">${getMaxPriceHTML(
        !!maxHasDecimal
      )}</span>`;
      break;
    case "min-only":
      innerHtml = `<span class="${className}__min">${getMinPriceHTML(!!minHasDecimal)}</span>`;
      break;
    case "max-only":
      innerHtml = `<span class="${className}__max">${getMaxPriceHTML(!!maxHasDecimal)}</span>`;
      break;
  }

  return `<span class="${className}">${innerHtml}</span>`;
}

/**
 * Generate HTML for a currency element
 */
export function generateCurrencyHTML(el: CurrencyElement, _useWebComponent: boolean): string {
  const className = getClassName(el.type);

  if (el.useCustomImage && el.customImageUrl) {
    return `<span class="${className}"><img src="${el.customImageUrl}" alt="Currency" class="${className}__img" /></span>`;
  }

  if (el.useCustomSvg && el.customSvg) {
    return `<span class="${className}">${el.customSvg}</span>`;
  }

  const symbol = el.symbol || "$";
  return `<span class="${className}">${symbol}</span>`;
}

/**
 * Generate HTML for a discount badge element
 */
export function generateDiscountBadgeHTML(el: DiscountBadgeElement, useWebComponent: boolean): string {
  const className = getClassName(el.type);

  if (useWebComponent) {
    let content: string;
    switch (el.format) {
      case "amount":
        content = "-{discountAmount}";
        break;
      case "custom": {
        const customContent = el.customFormat || "-{discount}%";
        if (customContent.includes("\n")) {
          const lines = customContent.split("\n");
          content = lines.map((line) => `<span class="oppb-discount-line">${line}</span>`).join("");
        } else {
          content = customContent;
        }
        break;
      }
      case "percentage":
      default:
        content = "-{discount}%";
        break;
    }
    return `<span class="${className}">${content}</span>`;
  }

  const previewText = el.format === "amount" ? "-$19.99" : "-20%";
  return `<span class="${className}">${previewText}</span>`;
}

/**
 * Generate HTML for text element
 */
export function generateTextElementHTML(el: TextElement): string {
  const className = getClassName(el.type);
  const text = el.text || "";

  if (text.includes("\n")) {
    const lines = text.split("\n");
    const linesHtml = lines.map((line) => `<span class="oppb-text-line">${escapeHtml(line) || "&nbsp;"}</span>`).join("");
    return `<span class="${className}">${linesHtml}</span>`;
  }

  return `<span class="${className}">${escapeHtml(text)}</span>`;
}

/**
 * Generate HTML for any element
 */
export function generateElementHTML(el: CanvasElement, useWebComponent: boolean): string {
  if (!el.visible) return "";

  let html: string;
  if (isPriceElement(el)) {
    html = generatePriceHTML(el, useWebComponent);
  } else if (isVariablePriceRangeElement(el)) {
    html = generateVariablePriceRangeHTML(el, useWebComponent);
  } else if (isCurrencyElement(el)) {
    html = generateCurrencyHTML(el, useWebComponent);
  } else if (isDiscountBadgeElement(el)) {
    html = generateDiscountBadgeHTML(el, useWebComponent);
  } else if (isTextElement(el)) {
    html = generateTextElementHTML(el);
  } else {
    html = `<span class="oppb-element"></span>`;
  }

  return html.replace(/^<span /, `<span data-element-id="${escapeHtml(el.id)}" `);
}
