function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

function _extends() { _extends = Object.assign || 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 _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }

function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }

function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }

function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }

function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }

function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }

function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }

/*
Copyright (c) 2018-2019 Uber Technologies, Inc.

This source code is licensed under the MIT license found in the
LICENSE file in the root directory of this source tree.
*/
import * as React from 'react';
import { getOverrides, mergeOverrides } from '../helpers/overrides.js';
import { LocaleContext } from '../locale/index.js';
import { Select, filterOptions } from '../select/index.js';
var MINUTE = 60;
var HOUR = MINUTE * 60;
var DAY = HOUR * 24;
var NOON = DAY / 2;

function dateToSeconds(date) {
  var seconds = date.getSeconds();
  var minutes = date.getMinutes() * MINUTE;
  var hours = date.getHours() * HOUR;
  return seconds + minutes + hours;
}

function secondsToHourMinute(seconds) {
  var d = new Date(seconds * 1000);
  return [d.getUTCHours(), d.getUTCMinutes()];
}

function secondsToLabel(seconds, format) {
  var _secondsToHourMinute = secondsToHourMinute(seconds),
      _secondsToHourMinute2 = _slicedToArray(_secondsToHourMinute, 2),
      hours = _secondsToHourMinute2[0],
      minutes = _secondsToHourMinute2[1];

  var zeroPrefix = function zeroPrefix(n) {
    return n < 10 ? "0".concat(n) : n;
  };

  if (format === '12') {
    var isAfterNoon = seconds >= NOON;

    if (isAfterNoon) {
      hours -= 12;
    }

    if (hours === 0) {
      hours = 12;
    }

    return "".concat(hours, ":").concat(zeroPrefix(minutes), " ").concat(isAfterNoon ? 'PM' : 'AM');
  }

  return "".concat(zeroPrefix(hours), ":").concat(zeroPrefix(minutes));
}
/**
 * Converts a time string, e.g. 10:00, to one or more possible TimePicker
 * options representing that time.
 */


function stringToOptions(str) {
  var format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '12';
  // leading zero is optional, AM/PM is optional
  var twelveHourRegex = /^(1[0-2]|0?[1-9]):([0-5][0-9]) ?([AaPp][Mm]?)?$/; // leading zero is optional

  var twentyFourHourRegex = /^([0-9]|0[0-9]|1[0-9]|2[0-3]):([0-5][0-9])$/;
  var regex = format === '12' ? twelveHourRegex : twentyFourHourRegex;
  var match = str.match(regex);

  if (!match) {
    return [];
  }

  var hours = Number(match[1]);
  var minutes = Number(match[2]);
  var hoursMinutes = [];

  switch (format) {
    case '24':
      {
        hoursMinutes = [{
          hours: hours,
          minutes: minutes
        }];
        break;
      }

    case '12':
    default:
      {
        var twelveHours = hours % 12;
        var meridiem = match[3]; // if there's no AM/PM, add both AM and PM options

        if (!meridiem) {
          hoursMinutes = [{
            hours: twelveHours,
            minutes: minutes
          }, {
            hours: twelveHours + 12,
            minutes: minutes
          }];
        } else {
          var twentyFourHours = meridiem.toLowerCase()[0] === 'a' ? twelveHours : twelveHours + 12;
          hoursMinutes = [{
            hours: twentyFourHours,
            minutes: minutes
          }];
        }

        break;
      }
  }

  return hoursMinutes.map(function (_ref) {
    var hours = _ref.hours,
        minutes = _ref.minutes;
    var secs = hours * 3600 + minutes * 60;
    return {
      id: secs,
      label: secondsToLabel(secs, format)
    };
  });
}

var TimePicker =
/*#__PURE__*/
function (_React$Component) {
  _inherits(TimePicker, _React$Component);

  function TimePicker() {
    var _getPrototypeOf2;

    var _this;

    _classCallCheck(this, TimePicker);

    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(TimePicker)).call.apply(_getPrototypeOf2, [this].concat(args)));

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "state", {
      steps: [],
      value: null
    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "handleChange", function (seconds) {
      var date = _this.props.value || new Date();

      var _secondsToHourMinute3 = secondsToHourMinute(seconds),
          _secondsToHourMinute4 = _slicedToArray(_secondsToHourMinute3, 2),
          hours = _secondsToHourMinute4[0],
          minutes = _secondsToHourMinute4[1];

      date.setHours(hours, minutes, 0);
      _this.props.onChange && _this.props.onChange(date);
    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "buildSteps", function () {
      var _this$props$step = _this.props.step,
          step = _this$props$step === void 0 ? 900 : _this$props$step;
      var stepCount = DAY / step;

      if (!Number.isInteger(stepCount)) {
        var previousStepCount = stepCount;
        stepCount = Math.round(stepCount);

        if (process.env.NODE_ENV !== "production") {
          // eslint-disable-next-line no-console
          console.warn("Provided step value (".concat(step, ") does not spread evenly across a day. Rounding from ").concat(previousStepCount, " total steps to ").concat(stepCount, "."));
        }
      }

      var options = [];

      for (var i = 0; i < DAY; i += step) {
        options.push(i);
      }

      return options;
    });

    _defineProperty(_assertThisInitialized(_assertThisInitialized(_this)), "creatableFilterOptions", function (options, filterValue, excludeOptions, newProps) {
      var result = stringToOptions(filterValue, _this.props.format);

      if (result.length) {
        return result;
      }

      return filterOptions(options, filterValue, excludeOptions, newProps);
    });

    return _this;
  }

  _createClass(TimePicker, [{
    key: "componentDidMount",
    value: function componentDidMount() {
      var steps = this.buildSteps();

      if (this.props.value instanceof Date) {
        this.setState({
          steps: steps,
          value: this.buildSelectedOption(this.props.value, this.props.format)
        });
      } else {
        var seconds = dateToSeconds(new Date());
        var closestStep = NOON;
        steps.forEach(function (step) {
          if (Math.abs(step - seconds) < Math.abs(closestStep - seconds)) {
            closestStep = step;
          }
        });
        this.setState({
          steps: steps,
          value: {
            id: closestStep,
            label: secondsToLabel(closestStep)
          }
        });
        this.handleChange(closestStep);
      }
    }
  }, {
    key: "componentDidUpdate",
    value: function componentDidUpdate(prevProps) {
      var formatChanged = prevProps.format !== this.props.format;
      var stepChanged = prevProps.step !== this.props.step;

      if (formatChanged || stepChanged) {
        var steps = this.buildSteps();
        this.setState({
          steps: steps
        });
      }
    }
  }, {
    key: "buildSelectedOption",
    value: function buildSelectedOption(value) {
      var format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '12';
      var secs = dateToSeconds(value);
      return {
        id: secs,
        label: secondsToLabel(secs, format)
      };
    }
  }, {
    key: "render",
    value: function render() {
      var _this2 = this;

      var _this$props$overrides = this.props.overrides,
          overrides = _this$props$overrides === void 0 ? {} : _this$props$overrides;

      var _getOverrides = getOverrides(overrides.Select, Select),
          _getOverrides2 = _slicedToArray(_getOverrides, 2),
          OverriddenSelect = _getOverrides2[0],
          selectProps = _getOverrides2[1];

      var selectOverrides = mergeOverrides({
        Dropdown: {
          style: {
            maxHeight: '126px'
          }
        }
      }, // $FlowFixMe
      selectProps.overrides); // $FlowFixMe

      selectProps.overrides = selectOverrides;
      var value = this.props.value instanceof Date ? this.buildSelectedOption(this.props.value, this.props.format) : this.state.value;
      return React.createElement(LocaleContext.Consumer, null, function (locale) {
        return React.createElement(OverriddenSelect, _extends({
          "aria-label": locale.datepicker.timePickerAriaLabel,
          disabled: _this2.props.disabled,
          error: _this2.props.error,
          positive: _this2.props.positive,
          options: _this2.state.steps.map(function (n) {
            return {
              id: n,
              label: secondsToLabel(n, _this2.props.format)
            };
          }),
          filterOptions: _this2.props.creatable ? _this2.creatableFilterOptions : undefined,
          onChange: function onChange(params) {
            _this2.setState({
              value: params.value[0]
            });

            var date = _this2.props.value || new Date();
            var seconds = params.value[0].id;

            var _secondsToHourMinute5 = secondsToHourMinute(seconds),
                _secondsToHourMinute6 = _slicedToArray(_secondsToHourMinute5, 2),
                hours = _secondsToHourMinute6[0],
                minutes = _secondsToHourMinute6[1];

            date.setHours(hours, minutes, 0);

            _this2.handleChange(params.value[0].id);
          },
          value: value,
          clearable: false
        }, selectProps));
      });
    }
  }]);

  return TimePicker;
}(React.Component);

_defineProperty(TimePicker, "defaultProps", {
  format: '12',
  step: 900,
  creatable: false
});

export default TimePicker;