// Locale-independent post-date formatting. Uses a fixed month table and
// UTC getters so the rendered string never varies by browser/CI locale
// or timezone (toLocaleDateString would make tests flaky).

const MONTHS = [
  'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
  'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
]

export function formatPostDate(iso) {
  if (!iso) return null
  const d = new Date(iso)
  if (isNaN(d.getTime())) return null
  return `${MONTHS[d.getUTCMonth()]} ${d.getUTCDate()}, ${d.getUTCFullYear()}`
}

// Compact relative formatter: "5m ago" (past) or "in 3h" (future). Null /
// invalid input returns `nullText`. Pass { future: true } for upcoming
// timestamps; a future time already elapsed reads as "imminent".
export function formatRelative(iso, opts = {}) {
  const { future = false, nullText = future ? '—' : 'Never' } = opts
  if (!iso) return nullText
  const then = new Date(iso).getTime()
  if (isNaN(then)) return nullText
  const diff = (then - Date.now()) / 1000  // +ve = future
  const abs = Math.abs(diff)
  let body
  if (abs < 60) body = `${Math.floor(abs)}s`
  else if (abs < 3600) body = `${Math.floor(abs / 60)}m`
  else if (abs < 86400) body = `${Math.floor(abs / 3600)}h`
  else body = `${Math.floor(abs / 86400)}d`
  if (future) return diff <= 0 ? 'imminent' : `in ${body}`
  return `${body} ago`
}

// Parse a backend timestamp as a UTC instant. Backend serializes tz-aware
// UTC (…+00:00); if a value ever arrives without a tz designator we treat
// it as UTC so it still converts to the viewer's zone correctly.
function _parseUtc (iso) {
  if (typeof iso !== 'string' || !iso) return null
  const hasTz = /([zZ])$|([+-]\d{2}:?\d{2})$/.test(iso)
  const d = new Date(hasTz ? iso : `${iso}Z`)
  return isNaN(d.getTime()) ? null : d
}

// Local-timezone date + time, e.g. "May 28, 7:30 PM". Use for absolute
// timestamps that were previously shown as raw UTC ISO.
export function formatDateTime (iso) {
  const d = _parseUtc(iso)
  if (!d) return ''
  return d.toLocaleString(undefined, {
    month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit',
  })
}

// Local-timezone date only, e.g. "May 28, 2026".
export function formatLocalDate (iso) {
  const d = _parseUtc(iso)
  if (!d) return ''
  return d.toLocaleDateString(undefined, {
    year: 'numeric', month: 'short', day: 'numeric',
  })
}
