import dateMath from '@elastic/datemath';
import moment from 'moment';

/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License
 * 2.0 and the Server Side Public License, v 1; you may not use this file except
 * in compliance with, at your election, the Elastic License 2.0 or the Server
 * Side Public License, v 1.
 */

/**
 * Reusable format time string util
 */
const ISO_FORMAT = 'YYYY-MM-DDTHH:mm:ss.SSSZ';
const INVALID_DATE = 'invalid_date';
const ROUND_DELIMETER = '/';
const relativeUnitsFromLargestToSmallest = ['y', 'M', 'w', 'd', 'h', 'm', 's'];
const DATE_MODES = {
  ABSOLUTE: 'absolute',
  RELATIVE: 'relative',
  NOW: 'now'
};
const useFormatTimeString = (timeString, dateFormat, roundUp = false, locale = 'en', euiI18nService) => {
  let lookupToken = euiI18nService.lookupToken;

  // i18n'd strings
  const nowDisplay = lookupToken('euiPrettyDuration.now', 'now');
  const invalidDateDisplay = lookupToken('euiPrettyDuration.invalid', 'Invalid date');
  const timeAsMoment = moment(timeString, ISO_FORMAT, true);
  if (timeAsMoment.isValid()) {
    return timeAsMoment.locale(locale).format(dateFormat);
  }
  if (timeString === 'now') {
    return nowDisplay;
  }
  const tryParse = dateMath.parse(timeString, {
    roundUp: roundUp
  });
  if (!moment(tryParse).isValid()) {
    return invalidDateDisplay;
  }
  if (moment.isMoment(tryParse)) {
    return `~ ${tryParse.locale(locale).fromNow()}`;
  }
  return timeString;
};
function toAbsoluteString(value, roundUp = false) {
  const valueAsMoment = dateMath.parse(value, {
    roundUp
  });
  if (!valueAsMoment) {
    return value;
  }
  if (!moment(valueAsMoment).isValid()) {
    return INVALID_DATE;
  }
  return valueAsMoment.toISOString();
}
function parseRelativeParts(value) {
  const matches = typeof value === 'string' && value.match(/now(([-+])([0-9]+)([smhdwMy])(\/[smhdwMy])?)?/);
  const operator = matches && matches[2];
  const count = matches && matches[3];
  const unit = matches && matches[4];
  const roundBy = matches && matches[5];
  if (count && unit) {
    const isRounded = roundBy ? true : false;
    const roundUnit = isRounded && roundBy ? roundBy.replace(ROUND_DELIMETER, '') : undefined;
    return {
      count: parseInt(count, 10),
      unit: operator === '+' ? `${unit}+` : unit,
      round: isRounded,
      ...(roundUnit ? {
        roundUnit
      } : {})
    };
  }
  const results = {
    count: 0,
    unit: 's',
    round: false
  };
  const duration = moment.duration(moment().diff(dateMath.parse(value)));
  let unitOp = '';
  for (let i = 0; i < relativeUnitsFromLargestToSmallest.length; i++) {
    // @ts-expect-error this is a string with the accepted time units
    const asRelative = duration.as(relativeUnitsFromLargestToSmallest[i]);
    if (asRelative < 0) unitOp = '+';
    if (Math.abs(asRelative) > 1) {
      results.count = Math.round(Math.abs(asRelative));
      results.unit = relativeUnitsFromLargestToSmallest[i] + unitOp;
      results.round = false;
      break;
    }
  }
  return results;
}
function toRelativeStringFromParts(relativeParts) {
  const count = relativeParts.count ?? 0;
  const isRounded = relativeParts.round ?? false;
  if (count === 0 && !isRounded) {
    return 'now';
  }
  const matches = (relativeParts.unit ?? 's').match(/([smhdwMy])(\+)?/);
  const unit = matches?.[1];
  const operator = matches && matches[2] ? matches[2] : '-';
  const round = isRounded ? `${ROUND_DELIMETER}${unit}` : '';
  return `now${operator}${count}${unit}${round}`;
}
function isRangeInvalid(start, end) {
  if (start === 'now' && end === 'now') {
    return true;
  }
  const startMoment = dateMath.parse(start);
  const endMoment = dateMath.parse(end, {
    roundUp: true
  });
  const isInvalid = !startMoment || !endMoment || !startMoment.isValid() || !endMoment.isValid() || !moment(startMoment).isValid() || !moment(endMoment).isValid() || startMoment.isAfter(endMoment);
  return isInvalid;
}
function getDateMode(value) {
  if (value === 'now') {
    return DATE_MODES.NOW;
  }
  if (value?.includes?.('now')) {
    return DATE_MODES.RELATIVE;
  }
  return DATE_MODES.ABSOLUTE;
}

export { DATE_MODES, INVALID_DATE, ISO_FORMAT, ROUND_DELIMETER, useFormatTimeString as default, getDateMode, isRangeInvalid, parseRelativeParts, relativeUnitsFromLargestToSmallest, toAbsoluteString, toRelativeStringFromParts, useFormatTimeString };
//# sourceMappingURL=index.js.map
