import moment from 'moment-timezone';
import * as RNLocalize from 'react-native-localize';
import sinon from 'sinon';

import { assert } from '~/test/utils';

import {
  formatDate,
  parseDate,
  parseFromUnix,
  DATE_FORMAT,
  DATE_FORMAT_12H,
  DATE_FORMAT_24H,
  DATE_FORMAT_ZULU_TIME,
  DATE_FORMATS,
} from './date';

describe('date', function () {
  const timezoneStub = sinon.stub(RNLocalize, 'getTimeZone');

  beforeEach(function () {
    timezoneStub.returns('UTC');
  });

  describe('formatDate', function () {
    it('default', function () {
      const date = moment('2020-06-03 15:34:02.1234 +0000 UTC', DATE_FORMAT_ZULU_TIME);
      expect(formatDate(date, DATE_FORMAT_12H)).toBe('03/06/2020 - 3:34 PM');
    });

    it('with America/Los_Angeles as timezone', function () {
      timezoneStub.returns('America/Los_Angeles');
      const date = moment('2020-06-03 15:34:02.1234 +0000 UTC', DATE_FORMAT_ZULU_TIME);
      expect(formatDate(date, DATE_FORMAT_24H)).toBe('03/06/2020 - 08:34');
    });
  });

  describe('parseDate', function () {
    const cases = [
      [DATE_FORMAT, 'July 9, 2020', [2020, 7, 9], true],
      [DATE_FORMAT_12H, '09/07/2019 - 5:33 AM', [2019, 7, 9, 5, 33, 0], true],
      [DATE_FORMAT_24H, '09/07/2019 - 16:33', [2019, 7, 9, 16, 33, 0], true],
      [DATE_FORMAT_ZULU_TIME, '2019-07-09T16:33:45Z', [2019, 7, 9, 16, 33, 45], false],
    ];

    test.each(cases)(
      'format %s',
      function (
        format: DATE_FORMATS,
        stringDate: string,
        expectedDate: number[],
        keepLocalTime: boolean,
      ) {
        const date = parseDate(stringDate, format);

        const [year, month, day, hour, minutes, seconds] = expectedDate;
        assert.dateEquals(date, year, month, day, hour, minutes, seconds, keepLocalTime);
      },
    );
  });

  describe('parseFromUnix', function () {
    it('with timestamp in seconds', function () {
      const timestamp = 1596553200; // 4 August 2020 15:00:00 UTC
      const date = parseFromUnix(timestamp);

      assert.dateEquals(date, 2020, 8, 4, 15, 0, 0);
    });

    it('with timestamp in milliseconds', function () {
      const timestamp = 1596553200000;
      const date = parseFromUnix(timestamp);

      assert.dateEquals(date, 2020, 8, 4, 15, 0, 0);
    });

    it('with timestamp in microseconds', function () {
      const timestamp = 1596553200000000;
      const date = parseFromUnix(timestamp);

      assert.dateEquals(date, 2020, 8, 4, 15, 0, 0);
    });

    it('with timestamp in nanoseconds', function () {
      const timestamp = 1596553200000000;
      const date = parseFromUnix(timestamp);

      assert.dateEquals(date, 2020, 8, 4, 15, 0, 0);
    });
  });
});
