"use strict";

require("core-js/modules/web.dom.iterable");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _time = require("@opentripplanner/core-utils/lib/time");

var _moment = _interopRequireDefault(require("moment"));

var _react = _interopRequireWildcard(require("react"));

var _reactBootstrap = require("react-bootstrap");

function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: 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 _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; }

const departureOptions = [{
  // Default option.
  children: 'Now',
  value: 'NOW'
}, {
  children: 'Depart at',
  value: 'DEPART'
}, {
  children: 'Arrive by',
  value: 'ARRIVE'
}];
/**
 * Time formats passed to moment.js used to parse the user's time input.
 */

const SUPPORTED_TIME_FORMATS = ['HH:mm:ss', 'h:mm:ss a', 'h:mm:ssa', 'h:mm a', 'h:mma', 'h:mm', 'HHmm', 'hmm', 'ha', 'h', 'HH:mm'].map(format => `YYYY-MM-DDT${format}`);
/**
 * Convert input moment object to date/time query params in OTP API format.
 * @param  {[type]} [time=moment(] [description]
 * @return {[type]}                [description]
 */

function momentToQueryParams(time = (0, _moment.default)()) {
  return {
    date: time.format(_time.OTP_API_DATE_FORMAT),
    time: time.format(_time.OTP_API_TIME_FORMAT)
  };
}
/**
 * Contains depart/arrive selector and time/date inputs for the admin-oriented
 * Call Taker form. A few unique features/behaviors to note:
 * - when "leave now" is selected the time/date will now stay up to date in the
 *   form and query params
 * - the time input will interpret various time formats using moment.js so that
 *   users can quickly type a shorthand value (5p) and have that be parsed into
 *   the correct OTP format.
 * - when a user changes the date or time, "leave now" (if selected) will
 *   automatically switch to "depart at".

 * @type {Object}
 */


class DateTimeOptions extends _react.Component {
  constructor(...args) {
    super(...args);

    _defineProperty(this, "state", {
      timeInput: ''
    });

    _defineProperty(this, "_updateTimeInput", (time = (0, _moment.default)()) => // If auto-updating time input (for leave now), use short 24-hr format to
    // avoid writing a value that is too long for the time input's width.
    this.setState({
      timeInput: time.format('H:mm')
    }));

    _defineProperty(this, "_startAutoRefresh", () => {
      const timer = window.setInterval(this._refreshDateTime, 1000);
      this.setState({
        timer
      });
    });

    _defineProperty(this, "_stopAutoRefresh", () => {
      window.clearInterval(this.state.timer);
      this.setState({
        timer: null
      });
    });

    _defineProperty(this, "_refreshDateTime", () => {
      const now = (0, _moment.default)();

      this._updateTimeInput(now);

      const dateTimeParams = momentToQueryParams(now); // Update query param if the current time has changed (i.e., on minute ticks).

      if (dateTimeParams.time !== this.props.time) {
        this.props.setQueryParam(dateTimeParams);
      }
    });

    _defineProperty(this, "_setDepartArrive", evt => {
      const {
        value: departArrive
      } = evt.target;

      if (departArrive === 'NOW') {
        const now = (0, _moment.default)(); // If setting to leave now, update date/time and start auto refresh to keep
        // form input in sync.

        this.props.setQueryParam({
          departArrive,
          ...momentToQueryParams(now)
        });

        if (!this.state.timer) {
          this._startAutoRefresh();
        }
      } else {
        // If set to depart at/arrive by, stop auto refresh.
        this._stopAutoRefresh();

        this.props.setQueryParam({
          departArrive
        });
      }
    });

    _defineProperty(this, "handleDateChange", evt => this.handleDateTimeChange({
      date: evt.target.value
    }));

    _defineProperty(this, "handleDateTimeChange", params => {
      const {
        departArrive: prevDepartArrive
      } = this.props; // If previously set to leave now, change to depart at when time changes.

      if (prevDepartArrive === 'NOW') params.departArrive = 'DEPART';
      this.props.setQueryParam(params);
    });

    _defineProperty(this, "handleTimeFocus", evt => evt.target.select());

    _defineProperty(this, "parseInputAsTime", (timeInput, date = (0, _moment.default)().startOf('day').format('YYYY-MM-DD')) => {
      return (0, _moment.default)(date + 'T' + timeInput, SUPPORTED_TIME_FORMATS);
    });

    _defineProperty(this, "dateTimeAsMoment", () => (0, _moment.default)(`${this.props.date}T${this.props.time}`));

    _defineProperty(this, "handleTimeChange", evt => {
      if (this.state.timer) this._stopAutoRefresh();
      const timeInput = evt.target.value;
      const parsedTime = this.parseInputAsTime(timeInput);
      this.handleDateTimeChange({
        time: parsedTime.format(_time.OTP_API_TIME_FORMAT)
      });
      this.setState({
        timeInput
      });
    });
  }

  componentDidMount() {
    if (this.props.departArrive === 'NOW') {
      this._startAutoRefresh();
    }
  }

  componentWillUnmount() {
    this._stopAutoRefresh();
  }

  componentDidUpdate(prevProps) {
    const {
      date,
      departArrive,
      time
    } = this.props;
    const dateTime = this.dateTimeAsMoment();
    const parsedTime = this.parseInputAsTime(this.state.timeInput, date); // Update time input if time changes and the parsed time does not match what
    // the user originally input (this helps avoid changing the time input while
    // the user is simultaneously updating it).

    if (prevProps.time !== time && !parsedTime.isSame(dateTime)) {
      this._updateTimeInput(dateTime);
    } // If departArrive has been changed to leave now, begin auto refresh.


    if (departArrive !== prevProps.departArrive) {
      if (departArrive === 'NOW') this._startAutoRefresh();else this._stopAutoRefresh();
    }
  }

  render() {
    const {
      departArrive,
      onKeyDown,
      timeFormat
    } = this.props;
    const {
      timeInput
    } = this.state;
    const dateTime = this.dateTimeAsMoment();
    const cleanTime = dateTime.format(timeFormat);
    return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("select", {
      onBlur: this._setDepartArrive,
      onChange: this._setDepartArrive,
      onKeyDown: onKeyDown,
      value: departArrive
    }, departureOptions.map(o => /*#__PURE__*/_react.default.createElement("option", _extends({
      key: o.value
    }, o)))), /*#__PURE__*/_react.default.createElement(_reactBootstrap.OverlayTrigger, {
      overlay: /*#__PURE__*/_react.default.createElement(_reactBootstrap.Tooltip, {
        id: "time-tooltip"
      }, cleanTime),
      placement: "bottom",
      trigger: ['focus', 'hover']
    }, /*#__PURE__*/_react.default.createElement("input", {
      className: "datetime-slim",
      onChange: this.handleTimeChange,
      onFocus: this.handleTimeFocus,
      onKeyDown: onKeyDown,
      style: {
        fontSize: 'inherit',
        lineHeight: '.8em',
        marginLeft: '3px',
        padding: '0px',
        width: '50px'
      },
      value: timeInput || dateTime.format('H:mm')
    })), /*#__PURE__*/_react.default.createElement("input", {
      className: "datetime-slim",
      onChange: this.handleDateChange,
      onKeyDown: onKeyDown,
      style: {
        fontSize: '14px',
        lineHeight: '1em',
        outline: 'none',
        width: '109px'
      },
      type: "date",
      value: dateTime.format('YYYY-MM-DD')
    }));
  }

}

exports.default = DateTimeOptions;
module.exports = exports.default;

//# sourceMappingURL=date-time-options.js