import type { CanvasElement } from "@/types";

type CanvasElementLike = Partial<CanvasElement> & {
  hidden?: boolean;
  text?: string;
  prefixText?: string;
  displayMode?: string;
};

/**
 * Convert element display name to camelCase slug (matches PHP CanvasPlaceholders).
 */
export function elementNameToSlug(name: string): string {
  const parts = name.trim().toLowerCase().split(/\s+/).filter(Boolean);
  if (parts.length === 0) {
    return "";
  }

  const [first, ...rest] = parts;
  return first + rest.map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
}

function dedupeSlug(slug: string, counts: Map<string, number>): string {
  const current = counts.get(slug) ?? 0;
  counts.set(slug, current + 1);

  if (current === 0) {
    return slug;
  }

  return `${slug}${current + 1}`;
}

/**
 * Build canvas placeholder replacements from elements.
 *
 * - text → `{slug}` from `text`
 * - variablePriceRange → `{slug}Prefix` from `prefixText`
 */
export function buildCanvasPlaceholderReplacements(
  elements: CanvasElementLike[]
): Record<string, string> {
  const replacements: Record<string, string> = {};
  const slugCounts = new Map<string, number>();

  for (const element of elements) {
    if (!element || element.hidden) {
      continue;
    }

    const type = element.type ?? "";
    const name = element.name ?? type;
    let slug = elementNameToSlug(name);

    if (!slug) {
      slug = elementNameToSlug(type);
    }

    if (!slug) {
      continue;
    }

    slug = dedupeSlug(slug, slugCounts);

    if (type === "text") {
      replacements[`{${slug}}`] = element.text ?? "";
      continue;
    }

    if (type === "variablePriceRange") {
      const displayMode = element.displayMode ?? "range";
      const fallback = displayMode === "up-to" ? "Up to" : "From";
      replacements[`{${slug}Prefix}`] = element.prefixText ?? fallback;
    }
  }

  return replacements;
}

/**
 * Replace canvas placeholders in HTML (dev preview / export modal).
 */
export function applyCanvasPlaceholders(
  html: string,
  elements: CanvasElementLike[]
): string {
  const replacements = buildCanvasPlaceholderReplacements(elements);

  return Object.entries(replacements).reduce(
    (output, [key, value]) => output.split(key).join(value),
    html
  );
}

/**
 * Describe canvas placeholders for the current layout (admin UI).
 */
export function describeCanvasPlaceholders(
  elements: CanvasElementLike[]
): Array<{ key: string; description: string }> {
  const slugCounts = new Map<string, number>();
  const docs: Array<{ key: string; description: string }> = [];

  for (const element of elements) {
    if (!element || element.hidden) {
      continue;
    }

    const type = element.type ?? "";
    const name = element.name ?? type;
    let slug = elementNameToSlug(name);

    if (!slug) {
      slug = elementNameToSlug(type);
    }

    if (!slug) {
      continue;
    }

    slug = dedupeSlug(slug, slugCounts);

    if (type === "text") {
      docs.push({
        key: `{${slug}}`,
        description: `Text from "${name}" element`,
      });
      continue;
    }

    if (type === "variablePriceRange") {
      docs.push({
        key: `{${slug}Prefix}`,
        description: `Prefix text from "${name}" variable range`,
      });
    }
  }

  return docs;
}
