/**
 * Locale-aware formatting helpers (Intl-based) + pluralization. Pair with the
 * request language (`ctx.lang`) so numbers, dates, and currencies render right
 * for each user.
 */

/** Format a number for a locale (e.g. 1234.5 → "1,234.5"). */
export function formatNumber(
  value: number,
  lang: string,
  options?: Intl.NumberFormatOptions,
): string {
  return new Intl.NumberFormat(lang || undefined, options).format(value);
}

/** Format a currency amount (e.g. 9.99, "USD" → "$9.99"). */
export function formatCurrency(value: number, currency: string, lang: string): string {
  return new Intl.NumberFormat(lang || undefined, { style: "currency", currency }).format(value);
}

/** Format a date/timestamp for a locale. */
export function formatDate(
  value: Date | number | string,
  lang: string,
  options: Intl.DateTimeFormatOptions = { dateStyle: "medium" },
): string {
  const date = value instanceof Date ? value : new Date(value);
  return new Intl.DateTimeFormat(lang || undefined, options).format(date);
}

/** Relative time, e.g. -3 days → "3 days ago" (localized). */
export function formatRelativeTime(
  value: number,
  unit: Intl.RelativeTimeFormatUnit,
  lang: string,
): string {
  return new Intl.RelativeTimeFormat(lang || undefined, { numeric: "auto" }).format(value, unit);
}

/**
 * Pick a plural form for `count` in `lang` using CLDR rules, e.g.
 * `plural(n, { one: "1 item", other: "# items" }, lang)` — "#" is replaced by n.
 */
export function plural(
  count: number,
  forms: Partial<Record<Intl.LDMLPluralRule, string>>,
  lang: string,
): string {
  const rule = new Intl.PluralRules(lang || undefined).select(count);
  const template = forms[rule] ?? forms.other ?? "";
  return template.replace(/#/g, String(count));
}
