/**
 * format.ts — locale-aware number, currency, and date formatters.
 * (rtl-hebrew-ui spec, wave 4)
 *
 * Thin wrappers around the browser's built-in Intl APIs.  All formatters
 * accept the Zync `Locale` type ('en' | 'he') and map it to a BCP-47 tag
 * internally, so callers never need to deal with locale string conversions.
 *
 * Currency: ILS only — Zync targets Israeli businesses.
 * Intl keeps digit order LTR even inside an RTL document, which is correct
 * Hebrew typography (numbers are read left-to-right in Hebrew invoices).
 *
 * Dates: Gregorian calendar by default.  Hebrew calendar support is out of
 * scope here — see spec 117 (hebrew-locale-dates) for that.
 */
import type { Locale } from '@zync/types'

/** Map from Zync locale ('en' | 'he') to BCP-47 tag used by Intl. */
const BCP47: Record<Locale, string> = {
  en: 'en-IL',
  he: 'he-IL',
}

/**
 * Format a numeric amount as Israeli New Shekel (ILS / ₪).
 *
 * Intl.NumberFormat keeps the digit sequence LTR even when the surrounding
 * document is RTL — this matches standard Hebrew typographic conventions for
 * invoices and financial documents.
 *
 * @param amount  - numeric value to format (e.g. 12500)
 * @param locale  - Zync locale ('he' | 'en')
 * @returns formatted string, e.g. '₪12,500' (he-IL) or '₪12,500' (en-IL)
 *
 * @example
 * formatCurrencyILS(12500, 'he') // '₪12,500'
 * formatCurrencyILS(12500, 'en') // '₪12,500'
 */
export function formatCurrencyILS(amount: number, locale: Locale): string {
  return new Intl.NumberFormat(BCP47[locale], {
    style: 'currency',
    currency: 'ILS',
    minimumFractionDigits: 0,
  }).format(amount)
}

/**
 * Format a number with optional Intl.NumberFormatOptions.
 *
 * @param value   - numeric value to format
 * @param locale  - Zync locale ('he' | 'en')
 * @param opts    - optional Intl.NumberFormatOptions overrides
 * @returns locale-formatted number string
 *
 * @example
 * formatNumber(0.185, 'he', { style: 'percent' }) // '18.5%' (he-IL)
 * formatNumber(1234.5, 'en')                       // '1,234.5'
 */
export function formatNumber(
  value: number,
  locale: Locale,
  opts?: Intl.NumberFormatOptions,
): string {
  return new Intl.NumberFormat(BCP47[locale], opts).format(value)
}

/**
 * Format a date value using the Gregorian calendar for the given locale.
 *
 * Accepts Date objects, ISO-8601 strings, or Unix timestamps (ms).
 * Hebrew calendar output is NOT provided here — see spec 117 for that.
 *
 * @param date    - Date, ISO-8601 string, or Unix timestamp
 * @param locale  - Zync locale ('he' | 'en')
 * @returns locale-formatted date string (Gregorian)
 *
 * @example
 * formatDate(new Date('2024-03-15'), 'he') // '15.3.2024' (he-IL)
 * formatDate(new Date('2024-03-15'), 'en') // Israeli-order English date via en-IL
 */
export function formatDate(date: Date | string | number, locale: Locale): string {
  return new Intl.DateTimeFormat(BCP47[locale]).format(new Date(date))
}
