import _extends from "@babel/runtime/helpers/extends";
import _defineProperty from "@babel/runtime/helpers/defineProperty";

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }

import React, { forwardRef, useImperativeHandle, useRef } from 'react';
import Box from '../box';
import cx from 'classnames';
import theme from './theme.css';
import NumericInput from './NumericInput';
var MINUTES_STEP = 15;
var DurationInput = /*#__PURE__*/forwardRef(function (_ref, forwardedRef) {
  var _getHoursString, _getMinutesString;

  var autoFocus = _ref.autoFocus,
      className = _ref.className,
      error = _ref.error,
      id = _ref.id,
      max = _ref.max,
      onBlur = _ref.onBlur,
      onChange = _ref.onChange,
      onFocus = _ref.onFocus,
      onKeyDown = _ref.onKeyDown,
      _ref$size = _ref.size,
      size = _ref$size === void 0 ? 'medium' : _ref$size,
      _ref$textAlignRight = _ref.textAlignRight,
      textAlignRight = _ref$textAlignRight === void 0 ? false : _ref$textAlignRight,
      value = _ref.value;
  var containerRef = useRef(null);
  useImperativeHandle(forwardedRef, function () {
    return containerRef.current;
  });

  var handleHoursChanged = function handleHoursChanged(_, hours) {
    if (!onChange) {
      return;
    }

    if (hours === '') {
      if (typeof (value === null || value === void 0 ? void 0 : value.minutes) === 'undefined') {
        onChange();
        return;
      }

      onChange({
        minutes: value === null || value === void 0 ? void 0 : value.minutes
      });
      return;
    }

    var parsedHours = parseInt(hours);

    if (!Number.isInteger(parsedHours)) {
      return;
    }

    onChange(_objectSpread(_objectSpread({}, value), {}, {
      hours: parsedHours
    }));
  };

  var handleMinutesChange = function handleMinutesChange(_, minutes) {
    if (!onChange) {
      return;
    }

    if (minutes === '') {
      if (typeof (value === null || value === void 0 ? void 0 : value.hours) === 'undefined') {
        onChange();
        return;
      }

      onChange({
        hours: value === null || value === void 0 ? void 0 : value.hours
      });
      return;
    }

    var parsedMinutes = parseInt(minutes);

    if (!Number.isInteger(parsedMinutes)) {
      return;
    }

    if (parsedMinutes > 60) {
      return;
    }

    if (parsedMinutes === 60) {
      onChange({
        hours: ((value === null || value === void 0 ? void 0 : value.hours) || 0) + 1,
        minutes: 0
      });
      return;
    }

    if (parsedMinutes < 0) {
      onChange({
        hours: ((value === null || value === void 0 ? void 0 : value.hours) || 1) - 1,
        minutes: 60 - MINUTES_STEP
      });
      return;
    }

    onChange(_objectSpread(_objectSpread({}, value), {}, {
      minutes: parsedMinutes
    }));
  };
  /**
   * This blur handler is a special one, because this input consists of multiple focus points:
   * the two inputs themselves, and the four increment/decrement buttons
   * we filter out the blur events caused by changing focus between these, so the onBlur event only
   * gets triggered when really blurring outside of the entire component
   */


  var handleBlur = function handleBlur(event) {
    var _containerRef$current, _containerRef$current2;

    if (!event.relatedTarget) {
      onBlur && onBlur(event);
      return;
    }

    var inputs = ((_containerRef$current = containerRef.current) === null || _containerRef$current === void 0 ? void 0 : _containerRef$current.getElementsByTagName('input')) || [];

    if (Array.from(inputs).find(function (node) {
      return node === event.relatedTarget;
    })) {
      return;
    }

    var buttons = ((_containerRef$current2 = containerRef.current) === null || _containerRef$current2 === void 0 ? void 0 : _containerRef$current2.getElementsByTagName('button')) || [];

    if (Array.from(buttons).find(function (node) {
      return node === event.relatedTarget;
    })) {
      return;
    }

    onBlur && onBlur(event);
  };

  var transformToPaddedNumber = function transformToPaddedNumber(number) {
    return number < 10 ? "0".concat(number) : number.toString();
  };

  var getHoursString = function getHoursString() {
    var hours = value === null || value === void 0 ? void 0 : value.hours;

    if (Number.isInteger(hours)) {
      return transformToPaddedNumber(hours);
    } else if (hours) {
      return hours.toString();
    }

    return undefined;
  };

  var getMinutesString = function getMinutesString() {
    var minutes = value === null || value === void 0 ? void 0 : value.minutes;

    if (Number.isInteger(minutes)) {
      return transformToPaddedNumber(minutes);
    } else if (minutes) {
      return minutes.toString();
    }

    return undefined;
  };

  var getMaxHoursAndMinutes = function getMaxHoursAndMinutes() {
    if (max) {
      return {
        maxHours: Math.floor(max / 60),
        maxMinutes: max % 60
      };
    }

    return {
      maxHours: undefined,
      maxMinutes: undefined
    };
  };

  var getMaxHourLength = function getMaxHourLength() {
    var _getMaxHoursAndMinute = getMaxHoursAndMinutes(),
        maxHours = _getMaxHoursAndMinute.maxHours;

    var hoursString = getHoursString();

    if (hoursString && maxHours) {
      var maxHourLength = maxHours.toString().length; // if it starts with 0, allow one more so we don't block typing (because we autopad the hours)

      if (hoursString.length >= maxHourLength && hoursString[0] === '0') {
        maxHourLength += 1;
      }

      return maxHourLength;
    }

    return undefined;
  };

  var getMaxMinuteLength = function getMaxMinuteLength() {
    var minutesString = getMinutesString(); // if it starts with 0, allow one more so we don't block typing (because we autopad the minutes)

    return minutesString && minutesString.length >= 2 && minutesString[0] !== '0' ? 2 : 3;
  };

  var isMaximumMinutesLimited = function isMaximumMinutesLimited() {
    var _getMaxHoursAndMinute2 = getMaxHoursAndMinutes(),
        maxHours = _getMaxHoursAndMinute2.maxHours; // Minutes are relative to the already filled in hours, so the max needs to be set on the fly


    return max && (value === null || value === void 0 ? void 0 : value.hours) && maxHours && value.hours >= maxHours || maxHours === 0;
  };

  return /*#__PURE__*/React.createElement(Box, {
    id: id,
    display: "flex",
    alignItems: "center",
    ref: containerRef,
    className: cx(className, theme['duration-input-numeric-container'], _defineProperty({}, theme['has-error'], error))
  }, /*#__PURE__*/React.createElement(NumericInput, _extends({
    placeholder: "00",
    min: 0
  }, max ? {
    max: getMaxHoursAndMinutes().maxHours
  } : {}, {
    maxLength: getMaxHourLength(),
    value: (_getHoursString = getHoursString()) !== null && _getHoursString !== void 0 ? _getHoursString : '',
    onChange: handleHoursChanged,
    onBlur: handleBlur,
    onFocus: onFocus,
    onKeyDown: onKeyDown,
    type: "text",
    inputMode: "numeric",
    className: theme['duration-input-numeric-input'],
    autoFocus: autoFocus,
    textAlignRight: textAlignRight,
    size: size
  })), /*#__PURE__*/React.createElement(NumericInput, _extends({
    placeholder: "00",
    step: MINUTES_STEP
  }, !(value !== null && value !== void 0 && value.hours) ? {
    min: 0
  } : {}, isMaximumMinutesLimited() ? {
    max: getMaxHoursAndMinutes().maxMinutes
  } : {}, {
    maxLength: getMaxMinuteLength(),
    value: (_getMinutesString = getMinutesString()) !== null && _getMinutesString !== void 0 ? _getMinutesString : '',
    onChange: handleMinutesChange,
    onBlur: handleBlur,
    onFocus: onFocus,
    onKeyDown: onKeyDown,
    type: "text",
    inputMode: "numeric",
    className: theme['duration-input-numeric-input'],
    textAlignRight: textAlignRight,
    size: size
  })));
});
DurationInput.displayName = 'DurationInput';
export default DurationInput;