var _excluded = ["disabled", "maxLength", "maxValue", "minValue", "nextRef", "onChange", "placeholder", "prevRef", "tabIndex", "type", "value"],
  _excluded2 = ["clearRef", "disabled", "error", "segmentRefs", "variant", "onChange", "onChangeSegment", "onClear", "tabIndex", "value"];
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i["return"] && (_r = _i["return"](), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
import { Clear } from '@procore/core-icons/dist';
import { getDatePartsWithPlaceholders } from '@procore/globalization-toolkit';
import { isSameDay } from 'date-fns';
import React from 'react';
import { Button } from '../Button/Button';
import { useDateTime } from '../_hooks/DateTime';
import { useI18nContext } from '../_hooks/I18n';
import { getMaxYear, maxMonth, minYear, normalizeNewDate } from '../_utils/CalendarHelpers';
import { StyledCalendar, StyledDateInput, StyledDateInputDelimiter, StyledDateInputIconContainer, StyledDateInputSegment, StyledDateSegmentsContainer } from './DateInput.styles';
var segmentMaxLengths = {
  day: 2,
  month: 2,
  year: 4
};
var dateInputLocales = {
  'fr-CA': {
    placeholders: {
      day: 'jj',
      month: 'mm',
      year: 'aaaa'
    }
  },
  'fr-FR': {
    placeholders: {
      day: 'jj',
      month: 'mm',
      year: 'aaaa'
    }
  },
  es: {
    placeholders: {
      day: 'dd',
      month: 'mm',
      year: 'aaaa'
    }
  },
  'es-ES': {
    placeholders: {
      day: 'dd',
      month: 'mm',
      year: 'aaaa'
    }
  },
  'pt-BR': {
    placeholders: {
      day: 'dd',
      month: 'mm',
      year: 'aaaa'
    }
  },
  'is-IS': {
    placeholders: {
      day: 'dd',
      month: 'mm',
      year: 'áááá'
    }
  },
  'de-DE': {
    placeholders: {
      day: 'tt',
      month: 'MM',
      year: 'jjjj'
    }
  }
};
var psuedoSegmentOrder = ['day', 'month', 'year'];
export function isValidYearRange(year) {
  return year > 1700 && year < 2122;
}
function noop() {}
function getLastDate(month, year) {
  return normalizeNewDate(year, Math.max(0, month), 0).getDate();
}
function getSegmentProps(onChangeSegment, type, placeholder, dateInput, getAriaLabel) {
  var maxLength = segmentMaxLengths[type];
  if (type === 'day') {
    return {
      'aria-label': getAriaLabel('day', dateInput.day),
      maxLength: maxLength,
      maxValue: getLastDate(dateInput.month, dateInput.year),
      minValue: 1,
      onChange: function onChange(value) {
        dateInput.setDay(value);
        onChangeSegment(type, value);
      },
      placeholder: placeholder,
      value: dateInput.day
    };
  } else if (type === 'month') {
    return {
      'aria-label': getAriaLabel('month', dateInput.month),
      maxLength: maxLength,
      maxValue: maxMonth,
      minValue: 1,
      onChange: function onChange(value) {
        dateInput.setMonth(value);
        onChangeSegment(type, value);
      },
      placeholder: placeholder,
      value: dateInput.month
    };
  } else {
    return {
      'aria-label': getAriaLabel('year', dateInput.year),
      maxLength: maxLength,
      maxValue: getMaxYear(),
      minValue: minYear,
      onChange: function onChange(value) {
        dateInput.setYear(value);
        onChangeSegment(type, value);
      },
      placeholder: placeholder,
      value: dateInput.year
    };
  }
}
function setFocusTo(target) {
  return target && target.current && target.current.focus();
}
function focusTargetOrFirst() {
  for (var _len = arguments.length, refs = new Array(_len), _key = 0; _key < _len; _key++) {
    refs[_key] = arguments[_key];
  }
  return function handler() {
    var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
      target: null
    };
    var ref = refs.reduce(function (acc, ref) {
      return ref.current && ref.current === event.target ? ref : acc;
    }, refs[0]);
    setFocusTo(ref);
  };
}
function clampDay(day, month, year) {
  if (day > 0 && month > 0 && year) {
    var date = normalizeNewDate(year, month - 1, day);
    if (date.getMonth() !== month - 1) {
      return getLastDate(month, year);
    }
  }
  return day;
}
function useDateInput(_ref) {
  var onChange = _ref.onChange,
    value_ = _ref.value,
    log = _ref.log;
  var dateTime = useDateTime();

  // logging called too frequenlty if not in memo
  var value = React.useMemo(function () {
    return dateTime.shiftUtcToZonedTime(value_, log);
  }, [value_]);
  var _React$useState = React.useState(value ? value.getDate() : -1),
    _React$useState2 = _slicedToArray(_React$useState, 2),
    day = _React$useState2[0],
    setRawDay = _React$useState2[1];
  var _React$useState3 = React.useState(value ? value.getMonth() + 1 : -1),
    _React$useState4 = _slicedToArray(_React$useState3, 2),
    month = _React$useState4[0],
    setRawMonth = _React$useState4[1];
  var _React$useState5 = React.useState(value ? value.getFullYear() : -1),
    _React$useState6 = _slicedToArray(_React$useState5, 2),
    year = _React$useState6[0],
    setRawYear = _React$useState6[1];
  var hasValues = day >= 0 || month >= 0 || year >= 0;
  var isInvalid = day < 0 || month < 0 || year < 0;
  var setAll = function setAll(day, month, year) {
    var clampedDay = clampDay(day, month, year);
    var date = clampedDay > 0 && month > 0 && year > 0 ? normalizeNewDate(year, month - 1, clampedDay) : null;
    setRawDay(clampedDay);
    setRawMonth(month);
    setRawYear(year);

    // Call DateSelect.onChange API when a supported year range or deleted date
    // isValidYearRange protects shiftZonedTimeToUtc
    // when date is null, year should be -1. -1 means it was cleared, either by button or backspace key
    /**
     * - going from non-valid date to a valid date
     *    - is a valid year range
     * - going from one valid date to another, different, date
     *    - is a valid year range
     * - change to invalid date
     */
    var validDate = date && isValidYearRange(year);
    if (!value && validDate || value && validDate && !isSameDay(date, value) || value && date === null) {
      onChange(dateTime.shiftZonedTimeToUtc(date));
    }
  };
  var setDay = function setDay(value) {
    setAll(value, month, year);
  };
  var setMonth = function setMonth(value) {
    setAll(day, value, year);
  };
  var setYear = function setYear(value) {
    setAll(day, month, value);
  };
  var clear = function clear() {
    setAll(-1, -1, -1);
  };
  React.useEffect(function () {
    if (value) {
      setRawDay(value.getDate());
      setRawMonth(value.getMonth() + 1);
      setRawYear(value.getFullYear());
    } else if (value === undefined) {
      setRawDay(-1);
      setRawMonth(-1);
      setRawYear(-1);
    }
  }, [value]);
  return {
    clear: clear,
    day: day,
    hasValues: hasValues,
    month: month,
    setDay: setDay,
    setMonth: setMonth,
    setYear: setYear,
    year: year
  };
}
function getSegmentText(_ref2) {
  var maxLength = _ref2.maxLength,
    placeholder = _ref2.placeholder,
    type = _ref2.type,
    value = _ref2.value;
  if (value < 0) {
    return placeholder;
  }
  if (type === 'year' && !isValidYearRange(value)) {
    return "".concat(value, "____").slice(0, 4);
  }
  return String(value).padStart(maxLength, '0');
}
var getTodaySegmentValue = function getTodaySegmentValue(type) {
  var today = new Date();
  if (type === 'month') {
    // months start from zero
    return today.getMonth() + 1;
  } else if (type === 'day') {
    return today.getDate();
  } else {
    return today.getFullYear();
  }
};
var DateSegment = /*#__PURE__*/React.forwardRef(function DateSegment(_ref3, ref) {
  var _ref3$disabled = _ref3.disabled,
    disabled = _ref3$disabled === void 0 ? false : _ref3$disabled,
    maxLength = _ref3.maxLength,
    maxValue = _ref3.maxValue,
    minValue = _ref3.minValue,
    nextRef = _ref3.nextRef,
    _ref3$onChange = _ref3.onChange,
    onChange = _ref3$onChange === void 0 ? function (value) {} : _ref3$onChange,
    placeholder = _ref3.placeholder,
    prevRef = _ref3.prevRef,
    _ref3$tabIndex = _ref3.tabIndex,
    tabIndex = _ref3$tabIndex === void 0 ? 0 : _ref3$tabIndex,
    type = _ref3.type,
    _ref3$value = _ref3.value,
    value = _ref3$value === void 0 ? 0 : _ref3$value,
    props = _objectWithoutProperties(_ref3, _excluded);
  var I18n = useI18nContext();
  var dateTime = useDateTime();
  var _React$useState7 = React.useState(''),
    _React$useState8 = _slicedToArray(_React$useState7, 2),
    keyBuffer = _React$useState8[0],
    setKeyBuffer = _React$useState8[1];
  var contains = function contains(key, keys) {
    return keys.indexOf(key) >= 0;
  };
  var onKeyDown = function onKeyDown(event) {
    event.stopPropagation();
    var key = event.key;
    if (contains(key, ['Up', 'ArrowUp', 'Down', 'ArrowDown', 'Backspace'])) {
      event.preventDefault();
    }
    if (contains(key, ['Up', 'ArrowUp', 'Down', 'ArrowDown']) && value === -1) {
      onChange(getTodaySegmentValue(type));
    } else if (contains(key, ['Up', 'ArrowUp'])) {
      onChange(value + 1 > maxValue ? minValue : Math.max(1, value + 1));
    } else if (contains(key, ['Down', 'ArrowDown'])) {
      onChange(value - 1 < minValue ? maxValue : value - 1);
    } else if (contains(key, ['Left', 'ArrowLeft'])) {
      setFocusTo(prevRef);
    } else if (contains(key, ['Right', 'ArrowRight'])) {
      setFocusTo(nextRef);
    } else if (contains(key, ['Backspace', 'Delete'])) {
      setKeyBuffer('');
      onChange(-1);

      // the segment is currently empty, go to the previous segment
      if (value === -1) {
        setFocusTo(prevRef);
      }
    } else if (!isNaN(parseInt(key, 10))) {
      if (keyBuffer.length === 0) {
        // current buffer is empty, initialize it
        setKeyBuffer(key);
        onChange(parseInt(key, 10));
      } else {
        // current buffer has text, add to it
        var newBuffer = keyBuffer + key;
        setKeyBuffer(newBuffer);
        onChange(Math.min(parseInt(newBuffer, 10), maxValue));
      }
    }
  };
  React.useEffect(function () {
    if (keyBuffer.length >= maxLength || keyBuffer.length === 1 && (type === 'day' && value > 3 || type === 'month' && value > 1)) {
      setFocusTo(nextRef);

      // Needed for year to reset as it does not move focus
      setKeyBuffer('');
    }
  });
  var getMonthName = function getMonthName(month) {
    var date = new Date();
    // months start from zero
    date.setMonth(month - 1);
    return dateTime.format(date, 'none', {
      month: 'long'
    });
  };
  var valueText = value === -1 ? I18n.t('core.dateInput.segment.ariaValueText.empty') : type === 'month' ? "".concat(value, " - ").concat(getMonthName(value)) : "".concat(value);
  return /*#__PURE__*/React.createElement(StyledDateInputSegment, _extends({
    ref: ref
  }, props, {
    role: "spinbutton",
    "aria-valuetext": valueText,
    "aria-valuenow": value == -1 ? getTodaySegmentValue(type) : value,
    "aria-valuemax": maxValue,
    "aria-valuemin": minValue,
    "data-placeholder": value < 0,
    disabled: disabled,
    isYear: type === 'year',
    onBlur: function onBlur() {
      if (type === 'year' && value !== -1 && value < 100) {
        onChange(2000 + value);
      }
      setKeyBuffer('');
    },
    onKeyDown: onKeyDown,
    tabIndex: disabled ? -1 : tabIndex
  }), getSegmentText({
    value: value,
    placeholder: placeholder,
    type: type,
    maxLength: maxLength
  }));
});

/**
 * @deprecatedSince 11
 * @deprecated Intended for internal library development.
 */
export var DateInput = /*#__PURE__*/React.forwardRef(function DateInput(_ref4, ref) {
  var _dateInputLocales$I;
  var clearRef = _ref4.clearRef,
    disabled = _ref4.disabled,
    _ref4$error = _ref4.error,
    error = _ref4$error === void 0 ? false : _ref4$error,
    _ref4$segmentRefs = _ref4.segmentRefs,
    segmentRefs = _ref4$segmentRefs === void 0 ? {} : _ref4$segmentRefs,
    variant = _ref4.variant,
    _ref4$onChange = _ref4.onChange,
    onChange = _ref4$onChange === void 0 ? noop : _ref4$onChange,
    _ref4$onChangeSegment = _ref4.onChangeSegment,
    onChangeSegment = _ref4$onChangeSegment === void 0 ? noop : _ref4$onChangeSegment,
    _ref4$onClear = _ref4.onClear,
    onClear = _ref4$onClear === void 0 ? noop : _ref4$onClear,
    _ref4$tabIndex = _ref4.tabIndex,
    tabIndex = _ref4$tabIndex === void 0 ? 0 : _ref4$tabIndex,
    value = _ref4.value,
    props = _objectWithoutProperties(_ref4, _excluded2);
  var I18n = useI18nContext();
  var dateInputRef = ref;
  var segment1Ref = segmentRefs.segmentOne || /*#__PURE__*/React.createRef();
  var segment2Ref = segmentRefs.segmentTwo || /*#__PURE__*/React.createRef();
  var segment3Ref = segmentRefs.segmentThree || /*#__PURE__*/React.createRef();
  var placeholders = ((_dateInputLocales$I = dateInputLocales[I18n.locale]) === null || _dateInputLocales$I === void 0 ? void 0 : _dateInputLocales$I.placeholders) || {
    day: 'dd',
    month: 'mm',
    year: 'yyyy'
  };
  var dateParts = getDatePartsWithPlaceholders(I18n.locale, placeholders);
  var delimiter = dateParts.filter(function (part) {
    return part.type === 'literal';
  }).reduce(function (acc, curr) {
    return [].concat(_toConsumableArray(acc), [curr.value]);
  }, []);
  var segmentParts = dateParts.filter(function (part) {
    return ['month', 'day', 'year'].includes(part.type);
  }).reduce(function (acc, curr) {
    return [].concat(_toConsumableArray(acc), [curr.type]);
  }, []);
  var segments = I18n.locale === 'pseudo' ? psuedoSegmentOrder : _toConsumableArray(segmentParts);
  var dateTime = useDateTime();
  var dateInput = useDateInput({
    onChange: onChange,
    value: value,
    log: 'Display date'
  });
  var onClickClear = function onClickClear(e) {
    setFocusTo(segment1Ref);
    dateInput.clear();
    onClear(e);
  };
  var getSegmentAriaLabel = function getSegmentAriaLabel(type, value) {
    return value && value !== -1 ? I18n.t(type, {
      value: value,
      scope: 'core.dateInput.segment.ariaLabel.withValue'
    }) : I18n.t(type, {
      scope: 'core.dateInput.segment.ariaLabel.withoutValue'
    });
  };
  return /*#__PURE__*/React.createElement(StyledDateInput, _extends({
    role: "group",
    "aria-label": value && isValidYearRange(dateInput.year) ? dateTime.format(value, 'weekday-date') : undefined,
    disabled: disabled || variant === 'disabled',
    error: error || variant === 'error' ||
    // -1 means placeholder yyyy is shown
    !isValidYearRange(dateInput.year) && dateInput.year !== -1,
    ref: dateInputRef
  }, props, {
    onClick: function onClick(e) {
      var _props$onClick;
      focusTargetOrFirst(segment1Ref, segment2Ref, segment3Ref)(e);
      (_props$onClick = props.onClick) === null || _props$onClick === void 0 ? void 0 : _props$onClick.call(props, e);
    }
  }), /*#__PURE__*/React.createElement(StyledDateSegmentsContainer, null, /*#__PURE__*/React.createElement(DateSegment, _extends({
    disabled: disabled,
    nextRef: segment2Ref,
    ref: segment1Ref,
    tabIndex: tabIndex,
    type: segments[0]
  }, getSegmentProps(onChangeSegment, segments[0], placeholders[segments[0]], dateInput, getSegmentAriaLabel))), delimiter[0] && /*#__PURE__*/React.createElement(StyledDateInputDelimiter, {
    "aria-hidden": true,
    visible: Boolean(value)
  }, delimiter[0]), /*#__PURE__*/React.createElement(DateSegment, _extends({
    disabled: disabled,
    nextRef: segment3Ref,
    prevRef: segment1Ref,
    ref: segment2Ref,
    tabIndex: tabIndex,
    type: segments[1]
  }, getSegmentProps(onChangeSegment, segments[1], placeholders[segments[1]], dateInput, getSegmentAriaLabel))), delimiter[1] && /*#__PURE__*/React.createElement(StyledDateInputDelimiter, {
    "aria-hidden": true,
    visible: Boolean(value)
  }, delimiter[1]), /*#__PURE__*/React.createElement(DateSegment, _extends({
    disabled: disabled,
    prevRef: segment2Ref,
    ref: segment3Ref,
    tabIndex: tabIndex,
    type: segments[2]
  }, getSegmentProps(onChangeSegment, segments[2], placeholders[segments[2]], dateInput, getSegmentAriaLabel))), delimiter[2] && /*#__PURE__*/React.createElement(StyledDateInputDelimiter, {
    "aria-hidden": true,
    visible: Boolean(value)
  }, delimiter[2])), /*#__PURE__*/React.createElement(StyledDateInputIconContainer, null, dateInput.hasValues ? /*#__PURE__*/React.createElement(Button, {
    "aria-label": I18n.t('core.dateInput.clearButton.ariaLabel'),
    onClick: onClickClear,
    ref: clearRef,
    size: "sm",
    variant: "tertiary",
    icon: /*#__PURE__*/React.createElement(Clear, {
      size: "sm"
    }),
    tabIndex: -1 // TODO revisit this accessibility
  }) : /*#__PURE__*/React.createElement(StyledCalendar, null)));
});
DateInput.displayName = 'DateInput';
//# sourceMappingURL=DateInput.js.map