"use strict";

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

var _preact = require("preact");

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

var _decimals = require("./utils/decimals");

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

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

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 IncrementorButtons extends _preact.Component {
  constructor(props) {
    super(props);
    this.state = this.getUpdatedStateForValue(this.getValueToShow());
  }

  getTargetNumberOfDecimals() {
    const {
      step = 1
    } = this.props;
    return (0, _decimals.getNumberOfDecimals)(step);
  }

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

    return value;
  }

  getUpdatedStateForValue(rawValue, isTrusted) {
    let {
      max
    } = this.props;

    if (max == null) {
      max = Infinity;
    }

    if (isTrusted) {
      return {
        error: null,
        asNumber: rawValue,
        internalTextValue: rawValue.toString(),
        isValid: true
      };
    }

    const maxLenBefore = max === Infinity ? 20 : max.toString().split('.')[0].length;
    const maxLenAfter = this.getTargetNumberOfDecimals();
    const cleaned = (0, _decimals.getCleanDecimalWithLimits)({
      maxLenBefore,
      maxLenAfter
    })(rawValue);
    const asNumber = this.getValueAsNumber(cleaned);
    const hasValue = !!rawValue;
    const error = hasValue ? this.getError(asNumber) : null;
    const isValid = hasValue && !error;
    return {
      error,
      asNumber: asNumber,
      internalTextValue: cleaned,
      isValid
    };
  }

  getValueToShow() {
    const {
      displayValue,
      value
    } = this.props;
    const targetNumberOfDecimals = this.getTargetNumberOfDecimals();
    let valueToShow = displayValue != null ? displayValue : value;

    if (!valueToShow) {
      valueToShow = targetNumberOfDecimals === 0 ? value : (0, _decimals.ensureDecimals)(value, targetNumberOfDecimals);
    }

    return valueToShow && valueToShow.toString ? valueToShow.toString() : '';
  }

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

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

    if (val > max) {
      return "max is ".concat(max);
    }

    if (val < min) {
      return "min is ".concat(min);
    }

    return;
  }

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

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

  render() {
    const {
      step = 1,
      max = Infinity,
      min = 0,
      className = '',
      width = '200px',
      showStep = true,
      unit = '',
      value,
      startingValue,
      name,
      style
    } = this.props;
    const {
      internalTextValue,
      error
    } = this.state;
    let stepDown = step;
    let stepUp = step;
    const effectiveValue = value != null ? value : startingValue;
    return (0, _preact.h)("div", {
      style: _objectSpread({}, style)
    }, error && (0, _preact.h)("div", {
      className: "flex items-center red mb1 nt1"
    }, (0, _preact.h)(_icon.Icon, {
      icon: "error",
      className: "mr2",
      size: "18"
    }), (0, _preact.h)("div", null, error)), (0, _preact.h)("div", {
      className: "flex items-center ".concat(className)
    }, (0, _preact.h)(_inputs.Input, {
      type: "text",
      style: {
        width
      },
      "data-e2e": "".concat(name, "Value"),
      className: 'mr2 f5' + (error ? 'bg-washed-red' : ''),
      value: internalTextValue,
      onInput: e => {
        const value = e.target.value;
        this.realUpdateValue(value);
      }
    }), unit && (0, _preact.h)("span", {
      className: "mr2 f5 fw6"
    }, unit), (0, _preact.h)(_plusMinus.MinusButton, {
      name: name,
      disabled: effectiveValue - stepDown < min,
      onClick: () => this.realUpdateValue(effectiveValue - stepDown, true)
    }, showStep ? step : null), (0, _preact.h)(_plusMinus.PlusButton, {
      name: name,
      disabled: effectiveValue + stepUp > max,
      onClick: () => this.realUpdateValue(effectiveValue + stepUp, true)
    }, showStep ? step : null)));
  }

}

exports.IncrementorButtons = IncrementorButtons;