'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.computeLatestScalarDate = exports.computeEarliestScalarDate = exports.normalizeDateString = exports.normalizeNaturalLanguageDateString = exports.normalizeISO8601DateString = undefined;

var _moment = require('moment');

var _moment2 = _interopRequireDefault(_moment);

var _sugarDate = require('sugar-date');

var _sugarDate2 = _interopRequireDefault(_sugarDate);

require('sugar-date/locales');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var normalizedDateFormat = 'YYYY-MM-DD';

/**
 * Normalizes an ISO 8601 date string, removing any time and time zone parts, if present.
 * CollectionSpace dates should be considered time zone-less, but they are returned from the REST
 * API as ISO 8601 datetimes with a time portion of T00:00:00Z (UTC). This function may be used to
 * convert this to a date without time/zone, for display to end users.
 * @param {string} dateString - The ISO 8601 date string
 * @returns {string} The normalized date string in the format YYYY-MM-DD, or null if the input
 * string is not a valid ISO 8601 date string.
 */

// FIXME: Don't include locales unless they're requested. This increases the size of the minified
// dist bundle by about 26 KB.
var normalizeISO8601DateString = exports.normalizeISO8601DateString = function normalizeISO8601DateString(dateString) {
  if (!dateString) {
    return null;
  }

  // Use parseZone to prevent conversion to local time, which could result in the date becoming
  // the previous day in time zones with a negative offset from UTC.

  var dateMoment = _moment2.default.parseZone(dateString, _moment2.default.ISO_8601);

  return dateMoment.isValid() ? dateMoment.format(normalizedDateFormat) : null;
};

/**
 * Normalizes a date string of unknown format, including natural language descriptions like
 * 'today', 'tomorrow', 'next Tuesday', and others. This function will accept ISO 8601 formatted
 * dates, but may not produce the same result as normalizeISO8601DateString. In particular, ISO
 * 8601 date strings that contain a time/zone are converted to local time by this function.
 * @param {string} dateString - The date string
 * @returns {string} The normalized date string in the format YYYY-MM-DD, or null if the input
 * string could not be interpreted as a date.
 */
var normalizeNaturalLanguageDateString = exports.normalizeNaturalLanguageDateString = function normalizeNaturalLanguageDateString(dateString) {
  var locale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'en';

  if (!dateString) {
    return null;
  }

  var date = _sugarDate2.default.Date.create(dateString, locale);

  return _sugarDate2.default.Date.isValid(date) ? _sugarDate2.default.Date.format(date, '%Y-%m-%d') : null;
};

/**
 * Normalizes a date string by first trying normalizeISO8601DateString, and falling back to
 * normalizeNaturalLanguageDateString if normalizeISO8601DateString returns null.
 * @param {string} dateString - The date string
 * @returns {string} The normalized date string in the format YYYY-MM-DD, or null if the input
 * string could not be interpreted as a date.
 */
var normalizeDateString = exports.normalizeDateString = function normalizeDateString(dateString) {
  var locale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'en';

  if (!dateString) {
    return null;
  }

  return normalizeISO8601DateString(dateString) || normalizeNaturalLanguageDateString(dateString, locale);
};

var momentFromYearMonthDay = function momentFromYearMonthDay(year, month, day /* , era */) {
  if (!year && (month || day) || !month && day) {
    return null;
  }

  var dateParts = [parseInt(year, 10)];

  if (month) {
    dateParts.push(parseInt(month, 10) - 1);

    if (day) {
      dateParts.push(parseInt(day, 10));
    }
  }

  var date = (0, _moment2.default)(dateParts);

  return date.isValid() ? date : null;
};

var computeEarliestScalarDate = exports.computeEarliestScalarDate = function computeEarliestScalarDate(structuredDate) {
  var year = structuredDate.dateEarliestSingleYear,
      month = structuredDate.dateEarliestSingleMonth,
      day = structuredDate.dateEarliestSingleDay,
      era = structuredDate.dateEarliestSingleEra;


  if (!year && !month && !day) {
    return '';
  }

  var date = momentFromYearMonthDay(year, month, day, era);

  // TODO: Handle BC dates. The old UI ignored the era.
  // TODO: Incorporate the qualifier value/unit. The old UI did nothing with these.

  return date ? date.format(normalizedDateFormat) : null;
};

var computeLatestScalarDate = exports.computeLatestScalarDate = function computeLatestScalarDate(structuredDate) {
  var year = structuredDate.dateLatestYear,
      month = structuredDate.dateLatestMonth,
      day = structuredDate.dateLatestDay;
  var era = structuredDate.dateLatestEra;


  if (!year && !month && !day) {
    // No latest date parts are specified. Inherit year, month, and day from earliest/single.

    var dateEarliestSingleYear = structuredDate.dateEarliestSingleYear,
        dateEarliestSingleMonth = structuredDate.dateEarliestSingleMonth,
        dateEarliestSingleDay = structuredDate.dateEarliestSingleDay;

    // TODO: What if no date parts are specified, but the era/certainty/qualifier is different than
    // the earliest/single?

    year = dateEarliestSingleYear;
    month = dateEarliestSingleMonth;
    day = dateEarliestSingleDay;
  }

  if (!year && !month && !day) {
    return '';
  }

  var date = momentFromYearMonthDay(year, month, day, era);

  if (!date) {
    return null;
  }

  if (!month) {
    date.endOf('year');
  } else if (!day) {
    date.endOf('month');
  }

  date.add(1, 'days');

  return date.format(normalizedDateFormat);
};