/**
 * format-date.ts — locale-aware date and time formatters.
 * (hebrew-locale-dates spec 117)
 *
 * All functions accept a BCP-47 formatting tag (e.g. 'he-IL' or 'en-IL') produced
 * by toFormattingLocale(). Callers obtain the tag via:
 *   const locale = toFormattingLocale(useLocale())
 *
 * Uses native Intl.DateTimeFormat — zero bundle cost, full Cloudflare Workers support.
 * No date-fns/moment imports for value formatting.
 *
 * Gregorian calendar only (spec 117 §Hebrew Calendar Note).
 * 24-hour clock (hour12: false) per Israeli business convention.
 */

/** Option sets for the four canonical display contexts. */
const DATE_SHORT = {
  day: '2-digit',
  month: '2-digit',
  year: 'numeric',
} as const satisfies Intl.DateTimeFormatOptions

const DATE_LONG = {
  day: 'numeric',
  month: 'long',
  year: 'numeric',
} as const satisfies Intl.DateTimeFormatOptions

const DATE_MONTH = {
  month: 'long',
  year: 'numeric',
} as const satisfies Intl.DateTimeFormatOptions

const DATETIME = {
  day: '2-digit',
  month: '2-digit',
  year: 'numeric',
  hour: '2-digit',
  minute: '2-digit',
  hour12: false,
} as const satisfies Intl.DateTimeFormatOptions

/**
 * Named display styles for date formatting.
 *
 * - `short`    → `31.05.2026`           (tables, cards, compact views)
 * - `long`     → `31 במאי 2026`         (detail views, headings)
 * - `month`    → `מאי 2026`             (invoice period selectors, report headers)
 * - `datetime` → `31.05.2026 14:30`     (audit log, notifications — 24-hour clock)
 */
export type DateStyle = 'short' | 'long' | 'month' | 'datetime'

/**
 * Format a date for display using the given locale formatting tag.
 *
 * @param date   - Date object to format
 * @param locale - BCP-47 formatting tag from toFormattingLocale(): 'he-IL' | 'en-IL'
 * @param style  - Display context (default 'short')
 * @returns Locale-formatted date string
 *
 * @example
 * const tag = toFormattingLocale('he')  // 'he-IL'
 * formatDate(new Date('2026-05-31'), tag, 'short')    // '31.05.2026'
 * formatDate(new Date('2026-05-31'), tag, 'long')     // '31 במאי 2026'
 * formatDate(new Date('2026-05-31'), tag, 'month')    // 'מאי 2026'
 * formatDate(new Date('2026-05-31T14:30:00'), tag, 'datetime') // '31.05.2026 14:30'
 */
export function formatDate(
  date: Date,
  locale: string,
  style: DateStyle = 'short',
): string {
  const opts: Intl.DateTimeFormatOptions =
    style === 'short'    ? DATE_SHORT
    : style === 'long'   ? DATE_LONG
    : style === 'month'  ? DATE_MONTH
    : DATETIME
  return new Intl.DateTimeFormat(locale, opts).format(date)
}

/**
 * Format a time-only value.
 *
 * @param date   - Date object
 * @param locale - BCP-47 formatting tag
 * @returns 24-hour time string, e.g. '14:30'
 *
 * @example
 * formatTime(new Date('2026-05-31T14:30:00'), 'he-IL') // '14:30'
 */
export function formatTime(date: Date, locale: string): string {
  return new Intl.DateTimeFormat(locale, {
    hour: '2-digit',
    minute: '2-digit',
    hour12: false,
  }).format(date)
}
