"use strict";

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

var _preact = require("preact");

var _classnames = _interopRequireDefault(require("classnames"));

var _icon = require("./icon");

var _inputs = require("./inputs");

var _timeString = require("./utils/time-string");

var _date = require("./utils/date");

var _plusMinus = require("./plus-minus");

var _msToTimeString = require("./utils/ms-to-time-string");

var _isToday = _interopRequireDefault(require("date-fns/isToday"));

var _button = require("./button");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (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 = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

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; }

class TimeIncrementorButtons extends _preact.Component {
  constructor(props) {
    super(props);
    this.handleTextInput = this.handleTextInput.bind(this);
    this.handleBlur = this.handleBlur.bind(this);
    this.getError = this.getError.bind(this);
    this.realUpdateValue = this.realUpdateValue.bind(this);
    this.startEditingDate = this.startEditingDate.bind(this);
    this.stopEditingDate = this.stopEditingDate.bind(this);
    this.handleDateInput = this.handleDateInput.bind(this);
    this.state = _objectSpread({
      editingDate: false
    }, this.getUpdatedStateForValue(this.getValueToShow()));
  }

  getValueAsNumber(value) {
    if (typeof value === 'string') {
      return Number(value);
    }

    return value;
  }

  getUpdatedStateForValue(rawValue, updatedText, updateDateText) {
    const error = this.getError(rawValue);
    return {
      error,
      asNumber: rawValue,
      internalTextValue: updatedText || (0, _msToTimeString.msToTimeString)(rawValue),
      internalDateString: updateDateText || (0, _date.toSimpleISODateString)(rawValue),
      isValid: !error && rawValue
    };
  }

  handleTextInput(e) {
    const newText = e.target.value;
    const newValue = (0, _timeString.timeStringToMs)(newText, this.props.value);

    if (newValue) {
      this.realUpdateValue(newValue, newText);
    } else {
      this.setState({
        error: 'Invalid time input use HH:MM',
        internalTextValue: newText
      });
    }
  }

  handleBlur() {
    this.realUpdateValue(this.props.value);
  }

  getValueToShow() {
    const {
      displayValue,
      value
    } = this.props;
    return displayValue != null ? displayValue : value;
  }

  startEditingDate() {
    this.setState({
      editingDate: true
    });
    setTimeout(() => {
      const input = this.base && this.base.querySelector('input[type=date]');

      if (input) {
        input.focus();
      }
    }, 300);
  }

  getError(val) {
    const {
      max,
      min
    } = this.props;

    if (isNaN(val)) {
      return "invalid value";
    }

    if (val > max) {
      return "max is ".concat((0, _date.toDateString)(max, true));
    }

    if (val < min) {
      return "min is ".concat((0, _date.toDateString)(min, true));
    }

    return null;
  }

  realUpdateValue(newValue, updatedText) {
    const {
      updateValue
    } = this.props;
    const changedState = this.getUpdatedStateForValue(newValue, updatedText);
    this.setState(changedState);

    if (!changedState.error) {
      updateValue(changedState.asNumber);
    }
  }

  handleDateInput(e) {
    const value = e.target.value;

    if (value) {
      const wrongTZDate = new Date(value);
      const asDate = new Date(wrongTZDate.setMinutes(wrongTZDate.getMinutes() + wrongTZDate.getTimezoneOffset()));
      const updatedMs = (0, _timeString.timeStringToMs)(this.state.internalTextValue, asDate);
      this.realUpdateValue(updatedMs);
    }
  }

  stopEditingDate() {
    this.setState({
      editingDate: false
    });
  }

  render({
    step = 60000,
    max = Infinity,
    min = 0,
    className = '',
    value,
    startingValue,
    name,
    style,
    wrap = true,
    showDate = 'always'
  }) {
    const shouldShowDate = showDate === 'never' ? false : showDate === 'always' || showDate === 'notToday' && !(0, _isToday.default)(value);
    const {
      internalTextValue,
      internalDateString,
      editingDate,
      error
    } = this.state;
    const effectiveValue = value != null ? value : startingValue;
    return (0, _preact.h)("div", {
      className: (0, _classnames.default)('dib', error && 'bg-washed-red br2 pa2', className),
      style: _objectSpread({}, style)
    }, (0, _preact.h)("div", {
      className: (0, _classnames.default)('flex items-center', wrap && 'flex-wrap')
    }, shouldShowDate && (editingDate ? (0, _preact.h)(_inputs.Input, {
      type: "date",
      onBlur: this.stopEditingDate,
      value: internalDateString,
      onInput: this.handleDateInput,
      className: "mr2"
    }) : (0, _preact.h)(_button.IconButton, {
      type: "button",
      icon: "edit",
      href: "#",
      className: "mid-gray mr2",
      onClick: this.startEditingDate
    }, (0, _date.toDateString)(effectiveValue))), (0, _preact.h)(_inputs.Input, {
      type: "text",
      name: "time",
      style: {
        width: '60px'
      },
      "data-e2e": "".concat(name, "Value"),
      className: 'mr2 f5' + (error ? 'bg-washed-red' : ''),
      value: internalTextValue,
      onInput: this.handleTextInput,
      onBlur: this.handleBlur
    }), (0, _preact.h)(_plusMinus.MinusButton, {
      name: name,
      disabled: effectiveValue - step < min,
      onClick: () => this.realUpdateValue(effectiveValue - step)
    }), (0, _preact.h)(_plusMinus.PlusButton, {
      name: name,
      disabled: effectiveValue + step > max,
      onClick: () => this.realUpdateValue(effectiveValue + step)
    })), error && (0, _preact.h)("div", {
      className: "flex items-center red mv1"
    }, (0, _preact.h)(_icon.Icon, {
      icon: "error",
      className: "mr1",
      size: "18"
    }), (0, _preact.h)("div", null, error)));
  }

}

exports.TimeIncrementorButtons = TimeIncrementorButtons;