"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof = require("@babel/runtime/helpers/typeof");
exports.__esModule = true;
exports["default"] = exports.DEFAULT_TIME_STYLE = exports.DEFAULT_STEP = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireWildcard(require("react"));
var _Input = _interopRequireDefault(require("../Input"));
var _DropdownBase = _interopRequireDefault(require("../DropdownBase"));
var _constants = require("./constants");
var _TimeInputSt = require("./TimeInput.st.css.js");
var _designSystemsLocaleUtils = require("@wix/design-systems-locale-utils");
var _context = require("../WixStyleReactEnvironmentProvider/context");
var _TimeInputUtils = require("./TimeInputUtils");
var _useEventCallback = require("../common/useEventCallback/useEventCallback");
var _excluded = ["dataHook", "className", "size", "suffix", "prefix", "status", "statusMessage", "invalidMessage", "border", "disabled", "placeholder", "readOnly", "autoSelect", "width", "timeStyle", "onChange", "onInvalid", "step", "noRightBorderRadius", "noLeftBorderRadius", "popoverProps", "onFocus", "onBlur", "excludePastTimes", "filterTime", "disableKeyboardType", "hideStatusSuffix", "value"];
var _jsxFileName = "/home/builduser/work/57e038ea7326c1ec/packages/wix-design-system/dist/cjs/TimeInput/TimeInput.jsx",
  _this = void 0;
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
var DEFAULT_STEP = exports.DEFAULT_STEP = 15;
var DEFAULT_TIME_STYLE = exports.DEFAULT_TIME_STYLE = 'short';
var ERROR_TYPES = {
  FORMAT: 'formatError',
  OUT_OF_BOUNDS: 'outOfBoundsError'
};
var initialState = {
  isDropdownOpen: false,
  inputValue: '',
  selectedId: null,
  customInputId: null,
  highlightedOptionId: null,
  error: false,
  selectionRange: false,
  deleteEvent: false,
  scrollToOption: null,
  lastSavedDate: null
};
function reducer(state, action) {
  switch (action.type) {
    case _constants.ACTION.RESET:
      return _objectSpread({}, initialState);
    case _constants.ACTION.SET_STATE:
      return _objectSpread(_objectSpread({}, state), action.payload);
    case _constants.ACTION.SET_ERROR:
      return _objectSpread(_objectSpread({}, state), {}, {
        error: true,
        validationType: action.payload
      });
    case _constants.ACTION.OPEN_DROPDOWN:
      return _objectSpread(_objectSpread({}, state), {}, {
        isDropdownOpen: true
      });
    case _constants.ACTION.CLOSE_DROPDOWN:
      return _objectSpread(_objectSpread({}, state), {}, {
        isDropdownOpen: false
      });
    case _constants.ACTION.DELETE_EVENT:
      return _objectSpread(_objectSpread({}, state), {}, {
        deleteEvent: true
      });
    default:
      return state;
  }
}
var TimeInput = /*#__PURE__*/_react["default"].forwardRef(function (_ref, ref) {
  var dataHook = _ref.dataHook,
    className = _ref.className,
    size = _ref.size,
    suffix = _ref.suffix,
    prefix = _ref.prefix,
    status = _ref.status,
    statusMessage = _ref.statusMessage,
    invalidMessage = _ref.invalidMessage,
    border = _ref.border,
    disabled = _ref.disabled,
    placeholder = _ref.placeholder,
    readOnly = _ref.readOnly,
    autoSelect = _ref.autoSelect,
    _ref$width = _ref.width,
    width = _ref$width === void 0 ? 'auto' : _ref$width,
    _ref$timeStyle = _ref.timeStyle,
    timeStyle = _ref$timeStyle === void 0 ? DEFAULT_TIME_STYLE : _ref$timeStyle,
    onChange = _ref.onChange,
    onInvalid = _ref.onInvalid,
    _ref$step = _ref.step,
    step = _ref$step === void 0 ? DEFAULT_STEP : _ref$step,
    noRightBorderRadius = _ref.noRightBorderRadius,
    noLeftBorderRadius = _ref.noLeftBorderRadius,
    popoverProps = _ref.popoverProps,
    onFocus = _ref.onFocus,
    onBlur = _ref.onBlur,
    excludePastTimes = _ref.excludePastTimes,
    filterTime = _ref.filterTime,
    disableKeyboardType = _ref.disableKeyboardType,
    hideStatusSuffix = _ref.hideStatusSuffix,
    value = _ref.value,
    rest = (0, _objectWithoutProperties2["default"])(_ref, _excluded);
  var inputRef = (0, _react.useRef)(null);
  var context = (0, _react.useContext)(_context.WixStyleReactEnvironmentContext);
  var _useReducer = (0, _react.useReducer)(reducer, initialState),
    _useReducer2 = (0, _slicedToArray2["default"])(_useReducer, 2),
    state = _useReducer2[0],
    dispatch = _useReducer2[1];
  var locale = rest.locale || context.locale || 'en';
  var valueAsDate = value ? new Date(value).setSeconds(0, 0) : undefined;
  var showError = invalidMessage && state.error;
  var autofillValue = state.selectionRange ? state.inputValue.substring(state.selectionRange.selectionStart) : null;
  var resolvedStatusMessage = showError ? invalidMessage : statusMessage;
  var timeFilter = (0, _react.useMemo)(function () {
    return (0, _TimeInputUtils.getTimeFilter)({
      excludePastTimes: excludePastTimes,
      filterTime: filterTime
    });
  }, [excludePastTimes, filterTime]);
  var timeSlots = (0, _react.useMemo)(function () {
    var slots = (0, _TimeInputUtils.getTimeSlots)({
      value: valueAsDate,
      timeStyle: timeStyle,
      locale: locale,
      step: step
    });
    return slots.filter(function (_ref2) {
      var id = _ref2.id;
      return timeFilter(new Date(id));
    });
  }, [valueAsDate, timeStyle, locale, step, timeFilter]);
  var handleOnInvalid = (0, _useEventCallback.useEventCallback)(function () {
    onInvalid == null || onInvalid({
      validationType: state.validationType,
      value: state.inputValue
    });
  });
  var syncExternalValue = (0, _react.useCallback)(function () {
    if (value === null) {
      dispatch({
        type: _constants.ACTION.RESET
      });
      return;
    }
    var timeSlot = valueAsDate ? (0, _TimeInputUtils.getTimeSlot)({
      value: valueAsDate,
      timeStyle: timeStyle,
      locale: locale
    }) : (0, _TimeInputUtils.getClosestTimeSlot)({
      value: valueAsDate,
      timeSlots: timeSlots
    });
    var selectedOption = timeSlot && timeSlots.find(function (slot) {
      return timeSlot.id === slot.id;
    });
    dispatch({
      type: _constants.ACTION.SET_STATE,
      payload: {
        inputValue: timeSlot && timeSlot.value,
        selectedId: selectedOption && selectedOption.id
      }
    });
  }, [value, valueAsDate, locale, timeSlots, timeStyle]);
  var openDropdown = (0, _react.useCallback)(function () {
    if (readOnly) {
      return;
    }
    if (state.selectedId || state.highlightedOptionId) {
      dispatch({
        type: _constants.ACTION.OPEN_DROPDOWN
      });
      return;
    }
    var closestTimeSlot = (0, _TimeInputUtils.getClosestTimeSlot)({
      value: new Date(state.customInputId || valueAsDate),
      timeSlots: timeSlots
    });
    if (!state.isDropdownOpen) {
      dispatch({
        type: _constants.ACTION.OPEN_DROPDOWN
      });
    }

    // Always scroll to the most relevant option once the list is displayed
    dispatch({
      type: _constants.ACTION.SET_STATE,
      payload: {
        scrollToOption: state.selectedId || state.highlightedOptionId || (closestTimeSlot == null ? void 0 : closestTimeSlot.id)
      }
    });
  }, [readOnly, state.isDropdownOpen, state.selectedId, state.highlightedOptionId, state.customInputId, timeSlots, valueAsDate]);
  var findSelectedOption = (0, _react.useCallback)(function () {
    if (state.selectedId) {
      return {
        id: state.selectedId,
        value: state.inputValue
      };
    }
    var highlightedOption = timeSlots.find(function (slot) {
      return slot.id === state.highlightedOptionId;
    });
    if (highlightedOption) {
      return highlightedOption;
    }
    if (state.inputValue && !state.selectedId) {
      var customValue = (0, _TimeInputUtils.getCustomTimeSlot)({
        value: state.inputValue,
        timeSlot: timeSlots[0].id,
        timeStyle: timeStyle,
        locale: locale
      });
      if (customValue) {
        return {
          value: customValue.value,
          customId: customValue.id
        };
      }
    }
  }, [locale, state.highlightedOptionId, state.inputValue, state.selectedId, timeSlots, timeStyle]);
  var validateAndSetOption = (0, _react.useCallback)(function (opt) {
    var _state$lastSavedDate$, _state$lastSavedDate, _date$getTime;
    var option = opt ? opt : findSelectedOption();

    // Validate
    if (!option) {
      dispatch({
        type: _constants.ACTION.SET_ERROR,
        payload: ERROR_TYPES.FORMAT
      });
      return;
    } else if (!timeFilter(new Date(option.id || option.customId))) {
      dispatch({
        type: _constants.ACTION.SET_ERROR,
        payload: ERROR_TYPES.OUT_OF_BOUNDS
      });
      return;
    }

    // Set selected option
    var date = option ? new Date(option.customId || option.id) : null;
    var hasDateChanged = ((_state$lastSavedDate$ = (_state$lastSavedDate = state.lastSavedDate) == null || _state$lastSavedDate.getTime == null ? void 0 : _state$lastSavedDate.getTime()) !== null && _state$lastSavedDate$ !== void 0 ? _state$lastSavedDate$ : null) !== ((_date$getTime = date == null || date.getTime == null ? void 0 : date.getTime()) !== null && _date$getTime !== void 0 ? _date$getTime : null);
    dispatch({
      type: _constants.ACTION.SET_STATE,
      payload: {
        selectedId: option.id,
        customInputId: option.customId,
        inputValue: option.value,
        selectionRange: false,
        isDropdownOpen: false,
        highlightedOptionId: null,
        error: false,
        lastSavedDate: date
      }
    });
    if (option && hasDateChanged) {
      onChange == null || onChange({
        date: date
      });
    }
    return option;
  }, [findSelectedOption, timeFilter, onChange, state.lastSavedDate]);
  var _onKeyDown = (0, _react.useCallback)(function (e, delegateKeyDown) {
    if (e.key === ' ' || e.key === 'Spacebar') return;
    if (!state.isDropdownOpen && e.key === 'ArrowDown') {
      openDropdown();
      return e.preventDefault();
    }
    delegateKeyDown(e);
    if (e.key === 'Backspace') {
      dispatch({
        type: _constants.ACTION.DELETE_EVENT
      });
    }
    if (state.isDropdownOpen) {
      switch (e.key) {
        case 'Escape':
          {
            dispatch({
              type: _constants.ACTION.CLOSE_DROPDOWN
            });
            return e.preventDefault();
          }
        case 'Enter':
          {
            dispatch({
              type: _constants.ACTION.CLOSE_DROPDOWN
            });
            inputRef.current.setSelectionRange(state.inputValue.length, state.inputValue.length);
            if (!state.error) {
              return validateAndSetOption();
            }
          }
      }
    }
  }, [state.isDropdownOpen, state.inputValue, openDropdown, validateAndSetOption, state.error]);
  var onInputChange = (0, _react.useCallback)(function (e) {
    var inputValue = e.target.value;
    var isDropdownOpen = state.isDropdownOpen;
    var selectedId = state.selectedId;
    var selectionRange = false;
    var error = false;
    var validationType;

    // Open dropdown when value is selected with keyboard and/or value is typed again
    if (!isDropdownOpen) {
      isDropdownOpen = true;
    }

    // Validate current input value
    if ((0, _TimeInputUtils.isInputInvalid)(e.target.value)) {
      error = true;
      validationType = ERROR_TYPES.FORMAT;
      isDropdownOpen = false;
    }

    // Unselect dropdown option if input value does not match any available time slot
    if (inputValue !== timeSlots[state.selectedId]) {
      selectedId = null;
    }
    var suggestedOption = (0, _TimeInputUtils.getSuggestedOption)({
      inputValue: inputValue,
      timeSlots: timeSlots,
      locale: locale
    });
    if (!state.deleteEvent && suggestedOption) {
      var autoFillValue = (0, _TimeInputUtils.getAutoFilledValue)({
        inputValue: inputValue,
        suggestedOption: suggestedOption,
        locale: locale
      });
      var inputWithAutoFill = inputValue + autoFillValue;
      inputValue = inputValue + autoFillValue;
      selectionRange = {
        selectionStart: inputWithAutoFill.length - autoFillValue.length,
        selectionEnd: inputWithAutoFill.length
      };
    }
    var highlightedOptionId = suggestedOption ? suggestedOption.id : null;
    dispatch({
      type: _constants.ACTION.SET_STATE,
      payload: {
        isDropdownOpen: isDropdownOpen,
        error: error,
        validationType: validationType,
        selectedId: selectedId,
        highlightedOptionId: highlightedOptionId,
        selectionRange: selectionRange,
        inputValue: inputValue,
        deleteEvent: false
      }
    });
  }, [state.deleteEvent, timeSlots, state.isDropdownOpen, state.selectedId, locale]);
  var onInputBlur = (0, _react.useCallback)(function (e) {
    onBlur == null || onBlur(e);
    if (state.isDropdownOpen) {
      dispatch({
        type: _constants.ACTION.CLOSE_DROPDOWN
      });
    }
    if (state.error) return;
    if (state.inputValue === '') {
      return onChange == null ? void 0 : onChange({
        date: null
      });
    }
    validateAndSetOption();
  }, [validateAndSetOption, onChange, onBlur, state.error, state.isDropdownOpen, state.inputValue]);
  (0, _react.useImperativeHandle)(ref, function () {
    return {
      focus: function focus() {
        inputRef.current.focus();
        openDropdown();
      },
      blur: function blur() {
        inputRef.current.blur();
      },
      clear: function clear() {
        dispatch({
          type: _constants.ACTION.RESET
        });
        onChange == null || onChange({
          date: null
        });
      }
    };
  }, [onChange, openDropdown]);
  (0, _react.useEffect)(syncExternalValue, [syncExternalValue]);
  (0, _react.useEffect)(function () {
    // Select range when suggestedInputValue is changed
    if (state.selectionRange) {
      inputRef.current.setSelectionRange(state.selectionRange.selectionStart, state.selectionRange.selectionEnd);
    }
  }, [state.selectionRange]);
  (0, _react.useEffect)(function () {
    if (state.error) {
      handleOnInvalid();
    }
  }, [handleOnInvalid, state.error, state.inputValue, state.validationType]);
  return /*#__PURE__*/_react["default"].createElement("div", {
    className: (0, _TimeInputSt.st)(_TimeInputSt.classes.root, className),
    style: {
      width: width
    },
    "data-hook": dataHook,
    "data-value": state.selectedId || valueAsDate,
    "data-locale": locale,
    "data-time-style": timeStyle,
    "data-autofill": autofillValue,
    "data-scroll-to-option": state.scrollToOption,
    "data-status-message": statusMessage,
    __self: _this,
    __source: {
      fileName: _jsxFileName,
      lineNumber: 472,
      columnNumber: 7
    }
  }, /*#__PURE__*/_react["default"].createElement(_DropdownBase["default"], (0, _extends2["default"])({
    dataHook: _constants.DATA_HOOK.TimeInputDropdown,
    open: state.isDropdownOpen,
    onClickOutside: function onClickOutside() {
      return dispatch({
        type: _constants.ACTION.CLOSE_DROPDOWN
      });
    },
    options: timeSlots,
    onSelect: validateAndSetOption,
    selectedId: state.selectedId,
    maxHeight: "216px",
    markedOptionId: state.highlightedOptionId,
    focusOnOption: state.highlightedOptionId,
    focusOnSelectedOption: true,
    scrollToOption: state.scrollToOption,
    onMouseDown: function onMouseDown(e) {
      return e.preventDefault();
    },
    autoFocus: false,
    dynamicWidth: true
  }, popoverProps, {
    __self: _this,
    __source: {
      fileName: _jsxFileName,
      lineNumber: 483,
      columnNumber: 9
    }
  }), function (_ref3) {
    var isOpen = _ref3.isOpen,
      activeDescendantId = _ref3.activeDescendantId,
      listboxId = _ref3.listboxId,
      delegateKeyDown = _ref3.delegateKeyDown;
    return /*#__PURE__*/_react["default"].createElement(_Input["default"], {
      dataHook: _constants.DATA_HOOK.TimeInputInput,
      size: size,
      status: showError ? 'error' : status,
      statusMessage: resolvedStatusMessage,
      suffix: suffix && /*#__PURE__*/_react["default"].createElement(_Input["default"].Affix, {
        __self: _this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 507,
          columnNumber: 35
        }
      }, suffix),
      prefix: prefix && /*#__PURE__*/_react["default"].createElement(_Input["default"].Affix, {
        __self: _this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 508,
          columnNumber: 35
        }
      }, prefix),
      border: border,
      disabled: disabled,
      placeholder: placeholder,
      value: state.inputValue,
      onChange: onInputChange,
      onInputClicked: openDropdown,
      onKeyDown: function onKeyDown(e) {
        return _onKeyDown(e, delegateKeyDown);
      },
      ref: inputRef,
      readOnly: readOnly,
      autoSelect: autoSelect,
      noLeftBorderRadius: noLeftBorderRadius,
      noRightBorderRadius: noRightBorderRadius,
      onFocus: onFocus,
      onBlur: onInputBlur,
      disableEditing: disableKeyboardType,
      hideStatusSuffix: hideStatusSuffix,
      ariaAutocomplete: "list",
      ariaExpanded: isOpen,
      ariaControls: isOpen ? listboxId : undefined,
      ariaActiveDescendant: isOpen ? activeDescendantId : undefined,
      __self: _this,
      __source: {
        fileName: _jsxFileName,
        lineNumber: 502,
        columnNumber: 15
      }
    });
  }));
});
TimeInput.displayName = 'TimeInput';
var _default = exports["default"] = TimeInput;