import _extends from '@babel/runtime/helpers/extends';
import _defineProperty from '@babel/runtime/helpers/defineProperty';
import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
import _merge from '../../node_modules/lodash-es/merge.js';
import 'core-js/modules/es.array.concat.js';
import 'core-js/modules/es.array.includes.js';
import 'core-js/modules/es.array.join.js';
import 'core-js/modules/es.number.constructor.js';
import 'core-js/modules/es.object.to-string.js';
import 'core-js/modules/es.regexp.exec.js';
import 'core-js/modules/es.regexp.to-string.js';
import 'core-js/modules/es.string.includes.js';
import 'core-js/modules/es.string.pad-start.js';
import 'core-js/modules/es.string.replace.js';
import 'core-js/modules/es.string.search.js';
import React__default, { useState } from 'react';
import PropTypes from 'prop-types';
import { TimePicker } from '@carbon/react';
import classnames from 'classnames';
import { settings } from '../../constants/Settings.js';
import { keyboardKeys } from '../../constants/KeyCodeConstants.js';
import { ChevronUp, ChevronDown } from '@carbon/icons-react';

var _excluded = ["spinner", "value", "children", "onClick", "onChange", "disabled", "invalid", "is12hour", "defaultTimegroup", "i18n", "testId"];
var iotPrefix = settings.iotPrefix;
var TIMEGROUPS = {
  HOURS: 'HOURS',
  MINUTES: 'MINUTES'
};
var propTypes = {
  /** renders the up/down buttons  */
  spinner: PropTypes.bool,
  /** a default value for the input  */
  value: PropTypes.string,
  /** a list of children to pass to the Carbon TimePicker component  */
  children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
  /** triggered on input click  */
  onClick: PropTypes.func,
  /** triggered on value change. Called with 3 parameters: newValue, event, meta
   * The meta object has a property called invalid that is either true or false
   * representing the validation status of the new input
   */
  onChange: PropTypes.func,
  /** disable the input  */
  disabled: PropTypes.bool,
  /** will display invalidText when set to true */
  invalid: PropTypes.bool,
  /** set a 12-hour timepicker instead of the default 24-hour  */
  is12hour: PropTypes.bool,
  /** the default selected timegroup (hours, minutes) */
  defaultTimegroup: PropTypes.oneOf([TIMEGROUPS.HOURS, TIMEGROUPS.MINUTES]),
  /** All the labels that need translation */
  i18n: PropTypes.shape({
    /** String for word 'increment' or function receiving the unit as param:
     * (timeUnit) => `Increment ${timeUnit}` */
    increment: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
    /** String for word 'decrement' or function receiving the unit as param:
     * (timeUnit) => `Decrement ${timeUnit}` */
    decrement: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
    hours: PropTypes.string,
    minutes: PropTypes.string
  }),
  testId: PropTypes.string
};
var defaultProps = {
  spinner: false,
  value: '',
  children: null,
  onClick: null,
  onChange: null,
  disabled: false,
  invalid: false,
  is12hour: false,
  defaultTimegroup: TIMEGROUPS.HOURS,
  i18n: {
    increment: 'Increment',
    decrement: 'Decrement',
    hours: 'hours',
    minutes: 'minutes'
  },
  testId: 'time-picker-spinner'
};
var getButtonLabel = function getButtonLabel(text, timeUnit) {
  return typeof text === 'function' ? text(timeUnit) : "".concat(text, " ").concat(timeUnit);
};
var TimePickerSpinner = function TimePickerSpinner(_ref) {
  var spinner = _ref.spinner,
    value = _ref.value,
    children = _ref.children,
    onClick = _ref.onClick,
    onChange = _ref.onChange,
    disabled = _ref.disabled,
    invalid = _ref.invalid,
    is12hour = _ref.is12hour,
    defaultTimegroup = _ref.defaultTimegroup,
    i18nProp = _ref.i18n,
    testId = _ref.testId,
    others = _objectWithoutProperties(_ref, _excluded);
  var i18n = _merge({}, defaultProps.i18n, i18nProp);
  var _useState = useState(value || ''),
    _useState2 = _slicedToArray(_useState, 2),
    pickerValue = _useState2[0],
    setPickerValue = _useState2[1];
  var _useState3 = useState(defaultTimegroup === TIMEGROUPS.MINUTES ? 1 : 0),
    _useState4 = _slicedToArray(_useState3, 2),
    currentTimeGroup = _useState4[0],
    setCurrentTimeGroup = _useState4[1];
  var _useState5 = useState(false),
    _useState6 = _slicedToArray(_useState5, 2),
    isInteractingWithSpinner = _useState6[0],
    setIsInteractingWithSpinner = _useState6[1];
  var _useState7 = useState(false),
    _useState8 = _slicedToArray(_useState7, 2),
    isSpinnerFocused = _useState8[0],
    setIsSpinnerFocused = _useState8[1];
  var _useState9 = useState(-1),
    _useState10 = _slicedToArray(_useState9, 2),
    keyUpOrDownPosition = _useState10[0],
    setKeyUpOrDownPosition = _useState10[1];
  var _useState11 = useState(null),
    _useState12 = _slicedToArray(_useState11, 2),
    focusTarget = _useState12[0],
    setFocusTarget = _useState12[1];
  var timePickerRef = /*#__PURE__*/React__default.createRef();
  var validate = function validate(newValue) {
    var isValid12HoursRegex = /^(1[0-2]|0?[1-9]):[0-5][0-9]$/;
    var isValid24HoursRegex = /^([01][0-9]|2[0-3]):([0-5][0-9])$/;
    return !(is12hour ? isValid12HoursRegex.test(newValue) : isValid24HoursRegex.test(newValue));
  };
  var handleArrowClick = function handleArrowClick(direction) {
    var timeGroups = pickerValue.split(':');
    if (timeGroups.length === 1) {
      timeGroups.push('00');
    }
    var isChangingHours = currentTimeGroup === 0;
    var groupValue = Number(timeGroups[currentTimeGroup]);
    var maxForGroup = isChangingHours ? is12hour ? 12 : 23 : 59;
    if (direction === 'down') {
      var lowestForGroup = isChangingHours && is12hour ? maxForGroup : 0;
      var newGroupValue = groupValue - 1;
      groupValue = groupValue - 1 < 0 ? maxForGroup : newGroupValue === 0 ? lowestForGroup : newGroupValue;
    } else {
      groupValue = groupValue + 1 > maxForGroup ? isChangingHours && is12hour ? 1 : 0 : groupValue + 1;
    }
    timeGroups[currentTimeGroup] = groupValue.toString().padStart(2, '0');
    var newValue = timeGroups.join(':');
    setPickerValue(newValue);
    if (onChange) {
      onChange(newValue, null, {
        invalid: validate(newValue)
      });
    }
    window.setTimeout(function () {
      if (focusTarget) {
        focusTarget.selectionStart = keyUpOrDownPosition;
        focusTarget.selectionEnd = keyUpOrDownPosition;
        setKeyUpOrDownPosition(-1);
      }
    }, 0);
  };
  var onInputClick = function onInputClick(e) {
    var target = e.currentTarget;
    setFocusTarget(target);
    setCurrentTimeGroup(target.selectionStart <= 2 ? 0 : 1);
    if (onClick) {
      onClick(e);
    }
  };
  var onInputChange = function onInputChange(e) {
    var currentValue = e.currentTarget.value;
    setPickerValue(currentValue);
    if (onChange) {
      onChange(currentValue, e, {
        invalid: validate(currentValue)
      });
    }
  };
  var preventNonAllowedKeyboardInput = function preventNonAllowedKeyboardInput(e) {
    var _e$currentTarget$valu;
    var isNumberChar = /\d/.test(e.key);
    var isOnlyColon = e.key === ':' && !((_e$currentTarget$valu = e.currentTarget.value) !== null && _e$currentTarget$valu !== void 0 && _e$currentTarget$valu.includes(':'));
    if (isNumberChar || isOnlyColon) {
      return true;
    }
    e.preventDefault();
    return false;
  };
  var onInputKeyDown = function onInputKeyDown(e) {
    var target = e.currentTarget;
    setFocusTarget(target);
    switch (e.key) {
      case keyboardKeys.UP:
      case keyboardKeys.DOWN:
        setKeyUpOrDownPosition(target.selectionStart);
        break;
      case keyboardKeys.BACKSPACE:
      case keyboardKeys.DELETE:
      case keyboardKeys.TAB:
      case keyboardKeys.END:
      case keyboardKeys.HOME:
      case keyboardKeys.LEFT:
      case keyboardKeys.RIGHT:
        break;
      default:
        return preventNonAllowedKeyboardInput(e);
    }
    return true;
  };
  var onInputBlur = function onInputBlur(e) {
    var target = e.currentTarget;
    var regex = /[^\d:]/g;
    if (target.value.search(regex) > -1) {
      setPickerValue(target.value.replace(regex, ''));
    }
  };
  var lastSelectionStart = -1;
  var onInputKeyUp = function onInputKeyUp(e) {
    switch (e.key) {
      case keyboardKeys.LEFT:
      case keyboardKeys.RIGHT:
        setCurrentTimeGroup(e.currentTarget.selectionStart <= 2 ? 0 : 1);

        // this is to fix the event hijacking from sibling components, ie. DatePicker
        // in this case we need to set the proper cursor position artificially
        if (e.currentTarget.selectionStart === lastSelectionStart) {
          if (e.key === keyboardKeys.LEFT) {
            e.currentTarget.selectionStart -= 1;
          } else {
            e.currentTarget.selectionStart += 1;
          }
          e.currentTarget.selectionEnd = e.currentTarget.selectionStart;
        }
        lastSelectionStart = e.currentTarget.selectionStart;
        break;
      case keyboardKeys.UP:
        handleArrowClick('up');
        break;
      case keyboardKeys.DOWN:
        handleArrowClick('down');
        break;
    }
  };
  var onArrowClick = function onArrowClick(direction) {
    setIsInteractingWithSpinner(true);
    handleArrowClick(direction);
  };
  var onArrowInteract = function onArrowInteract(fromFocus) {
    if (!isSpinnerFocused) {
      setIsSpinnerFocused(fromFocus);
    }
    setIsInteractingWithSpinner(true);
  };
  var onArrowStopInteract = function onArrowStopInteract(fromBlur) {
    if (fromBlur) {
      setIsSpinnerFocused(false);
      setIsInteractingWithSpinner(false);
    }
    if (!isSpinnerFocused) {
      setIsInteractingWithSpinner(false);
    }
  };
  var timeGroupForLabel = currentTimeGroup === 0 ? i18n.hours : i18n.minutes;
  return /*#__PURE__*/React__default.createElement("div", {
    "data-testid": "".concat(testId, "-wrapper"),
    className: classnames("".concat(iotPrefix, "--time-picker__wrapper"), _defineProperty(_defineProperty(_defineProperty(_defineProperty({}, "".concat(iotPrefix, "--time-picker__wrapper--with-spinner"), spinner), "".concat(iotPrefix, "--time-picker__wrapper--updown"), keyUpOrDownPosition > -1), "".concat(iotPrefix, "--time-picker__wrapper--show-underline"), isInteractingWithSpinner), "".concat(iotPrefix, "--time-picker__wrapper--show-underline-minutes"), currentTimeGroup === 1))
  }, /*#__PURE__*/React__default.createElement(TimePicker, _extends({
    ref: timePickerRef,
    onClick: onInputClick,
    onChange: onInputChange,
    value: pickerValue,
    onKeyDown: onInputKeyDown,
    onKeyUp: onInputKeyUp,
    onBlur: onInputBlur,
    disabled: disabled,
    "data-testid": testId,
    invalid: invalid
  }, others), children, spinner ? /*#__PURE__*/React__default.createElement("div", {
    className: "".concat(iotPrefix, "--time-picker__controls")
  }, /*#__PURE__*/React__default.createElement("button", {
    type: "button",
    className: "".concat(iotPrefix, "--time-picker__controls--btn up-icon"),
    onClick: function onClick() {
      return onArrowClick('up');
    },
    onMouseOver: function onMouseOver() {
      return onArrowInteract(false);
    },
    onMouseOut: function onMouseOut() {
      return onArrowStopInteract(false);
    },
    onFocus: function onFocus() {
      return onArrowInteract(true);
    },
    onBlur: function onBlur() {
      return onArrowStopInteract(true);
    },
    "aria-live": "polite",
    "aria-atomic": "true",
    title: getButtonLabel(i18n.increment, timeGroupForLabel),
    "aria-label": getButtonLabel(i18n.increment, timeGroupForLabel),
    disabled: disabled,
    "data-testid": "".concat(testId, "-up-button")
  }, /*#__PURE__*/React__default.createElement(ChevronUp, {
    className: "up-icon"
  })), /*#__PURE__*/React__default.createElement("button", {
    type: "button",
    className: "".concat(iotPrefix, "--time-picker__controls--btn down-icon"),
    onClick: function onClick() {
      return onArrowClick('down');
    },
    onMouseOver: function onMouseOver() {
      return onArrowInteract(false);
    },
    onMouseOut: function onMouseOut() {
      return onArrowStopInteract(false);
    },
    onFocus: function onFocus() {
      return onArrowInteract(true);
    },
    onBlur: function onBlur() {
      return onArrowStopInteract(true);
    },
    "aria-live": "polite",
    "aria-atomic": "true",
    title: getButtonLabel(i18n.decrement, timeGroupForLabel),
    "aria-label": getButtonLabel(i18n.decrement, timeGroupForLabel),
    disabled: disabled,
    "data-testid": "".concat(testId, "-down-button")
  }, /*#__PURE__*/React__default.createElement(ChevronDown, {
    className: "down-icon"
  }))) : null));
};
TimePickerSpinner.propTypes = propTypes;
TimePickerSpinner.defaultProps = defaultProps;
TimePickerSpinner.__docgenInfo = {
  "description": "",
  "methods": [],
  "displayName": "TimePickerSpinner",
  "props": {
    "spinner": {
      "defaultValue": {
        "value": "false",
        "computed": false
      },
      "description": "renders the up/down buttons",
      "type": {
        "name": "bool"
      },
      "required": false
    },
    "value": {
      "defaultValue": {
        "value": "''",
        "computed": false
      },
      "description": "a default value for the input",
      "type": {
        "name": "string"
      },
      "required": false
    },
    "children": {
      "defaultValue": {
        "value": "null",
        "computed": false
      },
      "description": "a list of children to pass to the Carbon TimePicker component",
      "type": {
        "name": "union",
        "value": [{
          "name": "arrayOf",
          "value": {
            "name": "node"
          }
        }, {
          "name": "node"
        }]
      },
      "required": false
    },
    "onClick": {
      "defaultValue": {
        "value": "null",
        "computed": false
      },
      "description": "triggered on input click",
      "type": {
        "name": "func"
      },
      "required": false
    },
    "onChange": {
      "defaultValue": {
        "value": "null",
        "computed": false
      },
      "description": "triggered on value change. Called with 3 parameters: newValue, event, meta\nThe meta object has a property called invalid that is either true or false\nrepresenting the validation status of the new input",
      "type": {
        "name": "func"
      },
      "required": false
    },
    "disabled": {
      "defaultValue": {
        "value": "false",
        "computed": false
      },
      "description": "disable the input",
      "type": {
        "name": "bool"
      },
      "required": false
    },
    "invalid": {
      "defaultValue": {
        "value": "false",
        "computed": false
      },
      "description": "will display invalidText when set to true",
      "type": {
        "name": "bool"
      },
      "required": false
    },
    "is12hour": {
      "defaultValue": {
        "value": "false",
        "computed": false
      },
      "description": "set a 12-hour timepicker instead of the default 24-hour",
      "type": {
        "name": "bool"
      },
      "required": false
    },
    "defaultTimegroup": {
      "defaultValue": {
        "value": "'HOURS'",
        "computed": false
      },
      "description": "the default selected timegroup (hours, minutes)",
      "type": {
        "name": "enum",
        "value": [{
          "value": "'HOURS'",
          "computed": false
        }, {
          "value": "'MINUTES'",
          "computed": false
        }]
      },
      "required": false
    },
    "i18n": {
      "defaultValue": {
        "value": "{\n  increment: 'Increment',\n  decrement: 'Decrement',\n  hours: 'hours',\n  minutes: 'minutes',\n}",
        "computed": false
      },
      "description": "All the labels that need translation",
      "type": {
        "name": "shape",
        "value": {
          "increment": {
            "name": "union",
            "value": [{
              "name": "string"
            }, {
              "name": "func"
            }],
            "description": "String for word 'increment' or function receiving the unit as param:\n(timeUnit) => `Increment ${timeUnit}`",
            "required": false
          },
          "decrement": {
            "name": "union",
            "value": [{
              "name": "string"
            }, {
              "name": "func"
            }],
            "description": "String for word 'decrement' or function receiving the unit as param:\n(timeUnit) => `Decrement ${timeUnit}`",
            "required": false
          },
          "hours": {
            "name": "string",
            "required": false
          },
          "minutes": {
            "name": "string",
            "required": false
          }
        }
      },
      "required": false
    },
    "testId": {
      "defaultValue": {
        "value": "'time-picker-spinner'",
        "computed": false
      },
      "description": "",
      "type": {
        "name": "string"
      },
      "required": false
    }
  }
};
var TimePickerSpinner$1 = TimePickerSpinner;

export { TIMEGROUPS, TimePickerSpinner$1 as default };
