import React, { forwardRef } from 'react';
import PropTypes from 'prop-types';
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
import isToday from 'dayjs/plugin/isToday';
import isYesterday from 'dayjs/plugin/isYesterday';
import isLeapYear from 'dayjs/plugin/isLeapYear';

dayjs.extend(relativeTime);
dayjs.extend(isToday);
dayjs.extend(isYesterday);
dayjs.extend(isLeapYear);

const propTypes = {
  /**
   * The date can be a number, a string, a Date or a dayjs compatible format.
   * It will be parsed by dayjs.
   */
  date: PropTypes.oneOfType([
    PropTypes.number,
    PropTypes.string,
    PropTypes.instanceOf(Date),
    PropTypes.instanceOf(dayjs),
  ]),

  /**
   * Use this props to override standard behavior and use specific date format.
   */
  format: PropTypes.string,
};

const defaultProps = {
  date: undefined,
  format: '',
};

const DATETIME_FORMAT = 'dddd D MMMM YYYY [at] HH:mm:ss';
const DATE_FORMAT = 'MMMM D, YYYY';
const TIME_FORMAT = 'HH[h]mm[min]';

const getFormat = (date) => {
  if (dayjs(date).isToday()) {
    return `Today, at ${dayjs(date).format(TIME_FORMAT)}`;
  }

  if (dayjs(date).isYesterday()) {
    return `Yesterday, at ${dayjs(date).format(TIME_FORMAT)}`;
  }

  if (dayjs(date).isYesterday()) {
    return `Yesterday, at ${dayjs(date).format(TIME_FORMAT)}`;
  }

  if (dayjs(date).year() < dayjs().year()) {
    if ((dayjs().year() - dayjs(date).year()) === 1) {
      return 'a year ago';
    }

    return `${dayjs().year() - dayjs(date).year()} years ago`;
  }

  return dayjs(date).format(DATE_FORMAT);
};

export const TimeDisplay = forwardRef((props, ref) => {
  const {
    date,
    format,
    ...attributes
  } = props;

  const display = format
    ? dayjs(date).format(format)
    : getFormat(date);

  return (
    <time dateTime={dayjs(date).format(DATETIME_FORMAT)} ref={ref} {...attributes}>{display}</time>
  );
});

TimeDisplay.propTypes = propTypes;
TimeDisplay.defaultProps = defaultProps;
