import type { Locale } from './config';

const localeTag: Record<Locale, string> = {
  en: 'en',
  fr: 'fr',
  ar: 'ar',
};

export interface DateFormattingContext {
  locale: Locale;
  timeZone: string;
}

export function formatDate(
  value: Date | number,
  context: DateFormattingContext,
  options: Intl.DateTimeFormatOptions = { dateStyle: 'medium' },
): string {
  return new Intl.DateTimeFormat(localeTag[context.locale], {
    calendar: 'gregory',
    numberingSystem: 'latn',
    timeZone: context.timeZone,
    ...options,
  }).format(value);
}

export function formatTime(
  value: Date | number,
  context: DateFormattingContext,
  options: Intl.DateTimeFormatOptions = { timeStyle: 'short' },
): string {
  return formatDate(value, context, options);
}

export function formatDateRange(
  start: Date | number,
  end: Date | number,
  context: DateFormattingContext,
  options: Intl.DateTimeFormatOptions = { dateStyle: 'medium' },
): string {
  const formatter = new Intl.DateTimeFormat(localeTag[context.locale], {
    calendar: 'gregory',
    numberingSystem: 'latn',
    timeZone: context.timeZone,
    ...options,
  });
  return formatter.formatRange(start, end);
}

export function formatNumber(
  value: number,
  locale: Locale,
  options: Intl.NumberFormatOptions = {},
): string {
  return new Intl.NumberFormat(localeTag[locale], {
    numberingSystem: 'latn',
    ...options,
  }).format(value);
}

export function formatPercent(value: number, locale: Locale): string {
  return formatNumber(value, locale, { style: 'percent', maximumFractionDigits: 1 });
}

export function formatCurrency(value: number, locale: Locale, currency: string): string {
  if (!/^[A-Z]{3}$/.test(currency)) {
    throw new Error('Currency must be an explicit ISO 4217 code.');
  }
  return formatNumber(value, locale, { style: 'currency', currency });
}

export function formatRelativeTime(
  value: number,
  unit: Intl.RelativeTimeFormatUnit,
  locale: Locale,
): string {
  return new Intl.RelativeTimeFormat(`${localeTag[locale]}-u-nu-latn`, {
    numeric: 'auto',
  }).format(value, unit);
}

export function formatPhoneNumber(value: string): string {
  return value.replace(/[^+\d]/g, '').replace(/(?!^)\+/g, '');
}

export function preserveIdentifier(value: string): string {
  return value.replace(/\s+/g, ' ');
}
