/**
 * Natural-sort comparator for mooring numbers (`^[A-Z]+\d+$`, e.g. A1, B12,
 * E18). Plain alphabetic sort orders them A1, A10, A11, A2 because '1' < '2'
 * in lexicographic terms; this comparator splits the prefix from the index so
 * A2 lands before A10 the way reps expect.
 *
 * Stable across the CRM: use this anywhere mooring numbers are presented in
 * a list (dropdowns, table sorts, public-map ordering, berth options).
 */
const MOORING_PATTERN = /^([A-Z]+)(\d+)$/;

export function compareMooringNumbers(a: string, b: string): number {
  const ma = MOORING_PATTERN.exec(a);
  const mb = MOORING_PATTERN.exec(b);
  // Fall back to plain locale compare for anything that doesn't match the
  // canonical shape so we never throw on unexpected input.
  if (!ma || !mb) return a.localeCompare(b);
  const [, prefixA, numA] = ma;
  const [, prefixB, numB] = mb;
  if (prefixA !== prefixB) return (prefixA ?? '').localeCompare(prefixB ?? '');
  return Number(numA) - Number(numB);
}

/** Sort an array of objects by their mooring-number field, in place safe. */
export function sortByMooring<T>(items: T[], pick: (item: T) => string): T[] {
  return [...items].sort((a, b) => compareMooringNumbers(pick(a), pick(b)));
}
