/**
 * Date display helpers. Timestamps cross the wire as UTC ISO-8601; Shamsi (Persian
 * calendar) display is a client concern (see money-and-types.md). We render via the
 * Intl Persian calendar — no date library needed.
 */

const SHAMSI_LOCALE = 'fa-IR-u-ca-persian';

/** Resolves the Intl locale for date formatting from the app locale. */
function intlLocale(locale: string): string {
  return locale === 'fa' ? SHAMSI_LOCALE : 'en-US';
}

/** Formats a UTC ISO timestamp as a localized date (Shamsi for `fa`, Gregorian for `en`). */
export function formatShamsiDate(
  iso: string | Date,
  locale: string = 'fa',
  options: Intl.DateTimeFormatOptions = { year: 'numeric', month: 'long', day: 'numeric' }
): string {
  const date = iso instanceof Date ? iso : new Date(iso);
  if (Number.isNaN(date.getTime())) return '';
  return new Intl.DateTimeFormat(intlLocale(locale), options).format(date);
}

/** Formats a UTC ISO timestamp as a localized date + time. */
export function formatShamsiDateTime(iso: string | Date, locale: string = 'fa'): string {
  return formatShamsiDate(iso, locale, {
    year: 'numeric',
    month: 'long',
    day: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
  });
}

/**
 * Month + year only (Shamsi for `fa`, Gregorian for `en`), e.g. «تیر ۱۴۰۳» — doubles as a stable
 * group key for a month-grouped timeline (two timestamps in the same calendar month always format
 * to the same string), so callers can group directly on this without separate Jalali arithmetic.
 */
export function formatShamsiMonthYear(iso: string | Date, locale: string = 'fa'): string {
  return formatShamsiDate(iso, locale, { year: 'numeric', month: 'long' });
}

/** Time only (hh:mm) — a chat bubble's stamp once its date lives on a separator instead (§3.2). */
export function formatShamsiTime(iso: string | Date, locale: string = 'fa'): string {
  return formatShamsiDate(iso, locale, { hour: '2-digit', minute: '2-digit' });
}

/**
 * Whole calendar days between two timestamps, comparing the **formatted date string** (not raw ms
 * subtraction, which is wrong across a DST/timezone boundary) — two timestamps format identically iff
 * they fall on the same calendar day in the active calendar system.
 */
function isSameCalendarDay(a: Date, b: Date, locale: string): boolean {
  return formatShamsiDate(a, locale) === formatShamsiDate(b, locale);
}

/**
 * A chat-style day-separator label: the caller's «امروز»/«دیروز» for the last two calendar days, else the
 * plain Shamsi date (e.g. «۲۵ تیر ۱۴۰۵»). Calendar-agnostic — it never does its own Jalali arithmetic,
 * only compares already-formatted date strings (see `isSameCalendarDay`).
 */
export function formatDaySeparator(
  iso: string | Date,
  locale: string,
  todayLabel: string,
  yesterdayLabel: string,
): string {
  const date = iso instanceof Date ? iso : new Date(iso);
  if (Number.isNaN(date.getTime())) return '';
  const now = new Date();
  if (isSameCalendarDay(date, now, locale)) return todayLabel;
  const yesterday = new Date(now);
  yesterday.setDate(yesterday.getDate() - 1);
  if (isSameCalendarDay(date, yesterday, locale)) return yesterdayLabel;
  return formatShamsiDate(date, locale);
}
