// Centralized date, time, and currency formatters for the entire app.
// All dates use Greek/European style (DD/MM/YY). Never use US-style (MM/DD/YY).
//
// Usage:
//   import { fmtDate, fmtDateTime, fmtDateShort, fmtDateFull, toDatetimeLocal, nowLocal } from '@/lib/formatters'

// ─── Locale ──────────────────────────────────────────────────────────────────
// el-GR gives DD/MM/YYYY ordering. en-GB is acceptable too (same day-first).
// We use el-GR for short numeric dates and en-GB for human-readable dates
// because en-GB gives English month names with day-first ordering.
const LOCALE = 'el-GR'
const LOCALE_LONG = 'en-GB'

// ─── Pre-built Intl formatters (fast — created once) ─────────────────────────

// "05/03/2026"  (DD/MM/YYYY)
const SHORT_DATE = new Intl.DateTimeFormat(LOCALE, {
  day: '2-digit', month: '2-digit', year: 'numeric',
})

// "5 Mar 2026"
const MEDIUM_DATE = new Intl.DateTimeFormat(LOCALE_LONG, {
  day: 'numeric', month: 'short', year: 'numeric',
})

// "5 March 2026"
const LONG_DATE = new Intl.DateTimeFormat(LOCALE_LONG, {
  day: 'numeric', month: 'long', year: 'numeric',
})

// "Wednesday, 5 March 2026"
const FULL_DATE = new Intl.DateTimeFormat(LOCALE_LONG, {
  weekday: 'long', day: 'numeric', month: 'long', year: 'numeric',
})

// "14:30" (24h)
const TIME_24H = new Intl.DateTimeFormat(LOCALE_LONG, {
  hour: '2-digit', minute: '2-digit', hour12: false,
})

// "2:30 pm" (12h)
const TIME_12H = new Intl.DateTimeFormat(LOCALE_LONG, {
  hour: 'numeric', minute: '2-digit', hour12: true,
})

// "Wed, 5 Mar 2026, 2:30 pm"
const FULL_DATETIME = new Intl.DateTimeFormat(LOCALE_LONG, {
  weekday: 'short', day: 'numeric', month: 'short', year: 'numeric',
  hour: 'numeric', minute: '2-digit', hour12: true,
})

// ─── Safe parse helper ───────────────────────────────────────────────────────

function safeDate(iso) {
  if (!iso) return null
  const d = new Date(iso)
  return Number.isNaN(d.getTime()) ? null : d
}

// ─── Exported formatters ─────────────────────────────────────────────────────

/** "05/03/2026" — short numeric, Greek style DD/MM/YYYY */
export function fmtDate(iso) {
  const d = safeDate(iso)
  return d ? SHORT_DATE.format(d) : '—'
}

/** "5 Mar 2026" — medium with abbreviated month */
export function fmtDateMedium(iso) {
  const d = safeDate(iso)
  return d ? MEDIUM_DATE.format(d) : '—'
}

/** "5 March 2026" — long with full month name */
export function fmtDateLong(iso) {
  const d = safeDate(iso)
  return d ? LONG_DATE.format(d) : '—'
}

/** "Wednesday, 5 March 2026" — full with weekday */
export function fmtDateFull(iso) {
  const d = safeDate(iso)
  return d ? FULL_DATE.format(d) : '—'
}

/** "5 March 2026, 2:30 pm" — date + time (12h) */
export function fmtDateTime(iso) {
  const d = safeDate(iso)
  if (!d) return '—'
  return `${LONG_DATE.format(d)}, ${TIME_12H.format(d).toLowerCase()}`
}

/** "5 Mar 2026, 14:30" — date + time (24h) */
export function fmtDateTimeMedium(iso) {
  const d = safeDate(iso)
  if (!d) return '—'
  return `${MEDIUM_DATE.format(d)}, ${TIME_24H.format(d)}`
}

/** "Wed, 5 Mar 2026, 2:30 pm" — full datetime for emails/comms */
export function fmtDateTimeFull(iso) {
  const d = safeDate(iso)
  return d ? FULL_DATETIME.format(d) : ''
}

/** "14:30:05" — time with seconds, 24h */
export function fmtTime24(iso) {
  const d = safeDate(iso)
  if (!d) return '—'
  return d.toLocaleTimeString(LOCALE_LONG, { hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false })
}

/** Relative time: "just now", "5 minutes ago", "3 days ago", etc. */
export function fmtRelative(iso) {
  const d = safeDate(iso)
  if (!d) return ''
  const seconds = Math.floor((Date.now() - d.getTime()) / 1000)
  if (seconds < 60) return 'just now'
  const m = Math.floor(seconds / 60)
  if (m < 60) return `${m} minute${m !== 1 ? 's' : ''} ago`
  const h = Math.floor(m / 60)
  if (h < 24) return `${h} hour${h !== 1 ? 's' : ''} ago`
  const days = Math.floor(h / 24)
  if (days < 7) return `${days} day${days !== 1 ? 's' : ''} ago`
  const w = Math.floor(days / 7)
  if (w < 5) return `${w} week${w !== 1 ? 's' : ''} ago`
  const mo = Math.floor(days / 30)
  if (mo < 12) return `${mo} month${mo !== 1 ? 's' : ''} ago`
  const y = Math.floor(days / 365)
  return `${y} year${y !== 1 ? 's' : ''} ago`
}

// ─── Form input helpers ──────────────────────────────────────────────────────

/**
 * Convert an ISO string to a `datetime-local` input value in LOCAL time.
 * Avoids the UTC-shift bug that toISOString().slice(0,16) causes.
 */
export function toDatetimeLocal(iso) {
  if (!iso) return ''
  const d = safeDate(iso)
  if (!d) return ''
  const pad = n => String(n).padStart(2, '0')
  return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`
}

/** Current local time as a `datetime-local` input value string. */
export function nowLocal() {
  const d = new Date()
  const pad = n => String(n).padStart(2, '0')
  return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`
}

/** Convert a `datetime-local` value to ISO date string for date-only inputs. */
export function toDateInput(iso) {
  if (!iso) return ''
  const d = safeDate(iso)
  if (!d) return ''
  const pad = n => String(n).padStart(2, '0')
  return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`
}

// ─── Currency ────────────────────────────────────────────────────────────────

/** Format number as euros: "1.250,00 €" (Greek locale) */
export function fmtEuro(n) {
  const f = parseFloat(n) || 0
  return f.toLocaleString('el-GR', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + ' €'
}
