/**
 * SKU generation helpers (F-100).
 *
 * Operators no longer have to type a SKU manually when creating a product.
 * The SKU is derived from the product title, normalised, and uniqued
 * against the existing SKU table.
 */

const SKU_PREFIX = 'MV';
const MAX_SKU_LENGTH = 100;
const SLUG_REGEX = /[^a-z0-9]+/g;

/**
 * Builds a SKU from a product title. The result is uppercase, ASCII-only,
 * uses hyphens as separators and starts with the `MV-` prefix to keep
 * SKUs aligned with the existing convention.
 *
 * Throws if `title` is empty or only punctuation.
 */
export function generateSkuFromTitle(title: string): string {
  const slug = title
    .normalize('NFD')
    .replace(/[\u0300-\u036f]/g, '')
    .toLowerCase()
    .replace(/&/g, ' and ')
    .replace(SLUG_REGEX, '-')
    .replace(/^-+|-+$/g, '')
    .replace(/-{2,}/g, '-');
  if (!slug) {
    throw new Error('Cannot generate a SKU from an empty title');
  }
  // Prefix + slug, trimmed to fit within MAX_SKU_LENGTH.
  const base = `${SKU_PREFIX}-${slug.toUpperCase()}`;
  return base.slice(0, MAX_SKU_LENGTH).replace(/-+$/, '');
}

/**
 * Returns a SKU that does not collide with `existing` (case-insensitive).
 * Appends `-2`, `-3`, … until a free one is found, truncating the base
 * to fit within MAX_SKU_LENGTH.
 */
export function uniqueSku(base: string, existing: ReadonlySet<string>): string {
  const lower = new Set([...existing].map((value) => value.toLowerCase()));
  const baseLower = base.toLowerCase();
  if (!lower.has(baseLower)) return base;
  let i = 2;
  while (true) {
    const suffix = `-${i}`;
    const trimmed = `${base}`.slice(0, MAX_SKU_LENGTH - suffix.length).replace(/-+$/, '');
    const candidate = `${trimmed}${suffix}`;
    if (!lower.has(candidate.toLowerCase())) return candidate;
    i += 1;
    if (i > 9999) {
      throw new Error('Cannot generate a unique SKU after 9999 attempts');
    }
  }
}
