import dayjs, { type Dayjs } from "dayjs"
import localizedFormat from "dayjs/plugin/localizedFormat"
import relativeTime from "dayjs/plugin/relativeTime"
import "dayjs/locale/fr"
import "dayjs/locale/en"

dayjs.extend(localizedFormat)
dayjs.extend(relativeTime)

const SUPPORTED_LOCALES = new Set(["fr", "en", "de", "es", "it", "pt", "nl", "pl", "ja", "zh"])

let activeLocale: string | null = null

/** Browser locale for dayjs (client); stable fallback on server. */
export function resolveMailDateLocale(): string {
  if (typeof navigator === "undefined") return "fr"
  const base = navigator.language.split("-")[0]?.toLowerCase() ?? "fr"
  return SUPPORTED_LOCALES.has(base) ? base : "en"
}

export function ensureMailDateLocale(): void {
  const next = resolveMailDateLocale()
  if (activeLocale === next) return
  dayjs.locale(next)
  activeLocale = next
}

export function parseMailDate(iso: string): Dayjs | null {
  if (!iso?.trim()) return null
  const d = dayjs(iso)
  return d.isValid() ? d : null
}

export type MailDateDisplayVariant = "list" | "preview" | "previewShort" | "detail"

const TWO_WEEKS_MS = 14 * 24 * 60 * 60 * 1000

function relativeSuffix(d: Dayjs, now: Dayjs): string {
  if (d.isAfter(now)) return ""
  return ` (${d.fromNow()})`
}

/** Colonne date de la liste (fuseau navigateur). */
export function formatMailListDate(iso: string, now: Dayjs = dayjs()): string {
  ensureMailDateLocale()
  const d = parseMailDate(iso)
  if (!d) return "—"

  if (d.isSame(now, "day")) {
    return d.format("LT")
  }
  if (d.isSame(now, "year")) {
    return d.format("D MMM")
  }
  return d.format("L")
}

/** En-tête / aperçu d’un message (fuseau navigateur). */
export function formatMailPreviewDate(iso: string, now: Dayjs = dayjs()): string {
  ensureMailDateLocale()
  const d = parseMailDate(iso)
  if (!d) return "—"

  const time = d.format("LT")

  if (d.isSame(now, "day")) {
    return `${time}${relativeSuffix(d, now)}`
  }

  const msAgo = now.valueOf() - d.valueOf()
  const withinTwoWeeks = msAgo >= 0 && msAgo < TWO_WEEKS_MS
  const datePart = d.format("ddd D MMM")

  if (withinTwoWeeks) {
    return `${datePart} ${time}${relativeSuffix(d, now)}`
  }
  if (d.isSame(now, "year")) {
    return `${datePart} ${time}`
  }
  return `${d.format("ddd D MMM YYYY")} ${time}`
}

/** Citations, impression, panneau « détails » (sans relatif). */
export function formatMailDetailDate(iso: string, now: Dayjs = dayjs()): string {
  ensureMailDateLocale()
  const d = parseMailDate(iso)
  if (!d) return "—"

  const time = d.format("LT")
  const datePart = d.format("ddd D MMM")
  if (d.isSame(now, "year")) {
    return `${datePart} ${time}`
  }
  return `${d.format("ddd D MMM YYYY")} ${time}`
}

export function formatMailDate(iso: string, variant: MailDateDisplayVariant): string {
  switch (variant) {
    case "list":
    case "previewShort":
      return formatMailListDate(iso)
    case "preview":
      return formatMailPreviewDate(iso)
    case "detail":
      return formatMailDetailDate(iso)
  }
}
