/**
 * Shared date/time presets for admin UI surfaces.
 *
 * Use presets when a screen only needs one of the common display shapes.
 * Pass custom Intl.DateTimeFormatOptions to formatDateTime for one-off layouts.
 */
export const DATE_TIME_FORMAT_PRESETS = {
  ADMIN: "admin",
  COMPACT: "compact",
  DATE_ONLY: "dateOnly",
  TIME_ONLY: "timeOnly",
} as const;

export type DateTimeFormatPreset =
  (typeof DATE_TIME_FORMAT_PRESETS)[keyof typeof DATE_TIME_FORMAT_PRESETS];

/**
 * Options for formatDateTime.
 *
 * These extend Intl.DateTimeFormatOptions, so callers can pass fields such as
 * day, month, year, hour, minute, timeZone, and hour12 directly.
 */
export interface FormatDateTimeOptions extends Intl.DateTimeFormatOptions {
  /** Locale override. Defaults to the browser/user environment. */
  locale?: string | string[];
}

const presetOptions: Record<DateTimeFormatPreset, Intl.DateTimeFormatOptions> = {
  [DATE_TIME_FORMAT_PRESETS.ADMIN]: {
    day: "numeric",
    hour: "numeric",
    minute: "2-digit",
    month: "short",
    year: "numeric",
  },
  [DATE_TIME_FORMAT_PRESETS.COMPACT]: {
    day: "numeric",
    hour: "numeric",
    minute: "2-digit",
    month: "short",
  },
  [DATE_TIME_FORMAT_PRESETS.DATE_ONLY]: {
    day: "numeric",
    month: "short",
    year: "numeric",
  },
  [DATE_TIME_FORMAT_PRESETS.TIME_ONLY]: {
    hour: "numeric",
    minute: "2-digit",
  },
};

function normalizeOptions(
  options: DateTimeFormatPreset | FormatDateTimeOptions = DATE_TIME_FORMAT_PRESETS.ADMIN,
): { formatOptions: Intl.DateTimeFormatOptions; locale?: string | string[] } {
  if (typeof options === "string") {
    return {
      formatOptions: presetOptions[options],
    };
  }

  const { locale, ...formatOptions } = options;

  return {
    formatOptions,
    locale,
  };
}

/**
 * Formats API date/time strings for admin UI.
 *
 * Defaults to DATE_TIME_FORMAT_PRESETS.ADMIN and treats WordPress-style
 * "YYYY-MM-DD HH:mm:ss" strings as UTC. Empty values return "-", and invalid
 * date strings are returned unchanged.
 *
 * @example
 * formatDateTime(connection.connectedAt)
 *
 * @example
 * formatDateTime(value, DATE_TIME_FORMAT_PRESETS.COMPACT)
 *
 * @example
 * formatDateTime(value, {
 *   day: "numeric",
 *   hour: "numeric",
 *   minute: "2-digit",
 *   month: "short",
 *   year: "numeric",
 * })
 */
export function formatDateTime(
  value?: string,
  options?: DateTimeFormatPreset | FormatDateTimeOptions,
): string {
  const { formatOptions, locale } = normalizeOptions(options);

  if (!value) {
    return "-";
  }

  const normalizedValue = value.includes("T") ? value : `${value.replace(" ", "T")}Z`;
  const date = new Date(normalizedValue);

  if (Number.isNaN(date.getTime())) {
    return value;
  }

  return new Intl.DateTimeFormat(locale, formatOptions).format(date);
}
