// Copyright 2018-2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only

import moment from 'moment';
import type { LocalizerType } from '../types/Util';

// Only applies in the english locales, but it ensures that the format
//   is what we want.
function replaceSuffix(time: string) {
  return time.replace(/ PM$/, 'pm').replace(/ AM$/, 'am');
}

const getExtendedFormats = (i18n: LocalizerType) => ({
  y: 'lll',
  M: `${i18n('timestampFormat_M') || 'MMM D'} LT`,
  d: 'ddd LT',
});
const getShortFormats = (i18n: LocalizerType) => ({
  y: 'll',
  M: i18n('timestampFormat_M') || 'MMM D',
  d: 'ddd',
});

function isToday(timestamp: moment.Moment) {
  const today = moment().format('ddd');
  const targetDay = moment(timestamp).format('ddd');

  return today === targetDay;
}

function isYear(timestamp: moment.Moment) {
  const year = moment().format('YYYY');
  const targetYear = moment(timestamp).format('YYYY');

  return year === targetYear;
}

export function formatRelativeTime(
  rawTimestamp: number | Date,
  options: { extended?: boolean; i18n: LocalizerType }
): string {
  const { extended, i18n } = options;

  const formats = extended ? getExtendedFormats(i18n) : getShortFormats(i18n);
  const timestamp = moment(rawTimestamp);
  const now = moment();
  const diff = moment.duration(now.diff(timestamp));

  if (diff.years() >= 1 || !isYear(timestamp)) {
    return replaceSuffix(timestamp.format(formats.y));
  }
  if (diff.months() >= 1 || diff.days() > 6) {
    return replaceSuffix(timestamp.format(formats.M));
  }
  if (diff.days() >= 1 || !isToday(timestamp)) {
    return replaceSuffix(timestamp.format(formats.d));
  }
  if (diff.hours() >= 1) {
    return i18n('hoursAgo', [String(diff.hours())]);
  }
  if (diff.minutes() >= 1) {
    return i18n('minutesAgo', [String(diff.minutes())]);
  }

  return i18n('justNow');
}
