'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

const index = require('./index-a7b0c73d.js');
const core = require('@sankhyalabs/core');
const CSSVarsUtils = require('./CSSVarsUtils-f20973d1.js');
const index$1 = require('./index-1be40f19.js');

const ezNumberInputCss = ":host{--ez-number-input__min-width:0px;--ez-number-input__max-width:100%;display:block;width:100%}.number__input{height:100%;min-width:var(--ez-number-input__min-width);max-width:var(--ez-number-input__max-width)}";

const EzNumberInput = class {
  constructor(hostRef) {
    index.registerInstance(this, hostRef);
    this.ezChange = index.createEvent(this, "ezChange", 7);
    this.ezStartChange = index.createEvent(this, "ezStartChange", 7);
    this.ezCancelWaitingChange = index.createEvent(this, "ezCancelWaitingChange", 7);
    this._focused = false;
    this._changePending = false;
    this._valuePromiseCallbacks = [];
    this._value = undefined;
    this.label = undefined;
    this.value = undefined;
    this.enabled = true;
    this.canShowError = true;
    this.errorMessage = undefined;
    this.allowNegative = true;
    this.precision = undefined;
    this.prettyPrecision = undefined;
    this.mode = "regular";
    this.autoFocus = false;
    this.alternativePlaceholder = undefined;
  }
  /**
   * Aplica o foco no campo.
   */
  async setFocus(options) {
    this._textInput.setFocus(options);
  }
  /**
   * Remove o foco do campo.
   */
  async setBlur() {
    this._textInput.setBlur();
  }
  /**
   * Retorna se o conteúdo é inválido.
   */
  async isInvalid() {
    return typeof this.errorMessage === "string" && this.errorMessage.trim() !== "";
  }
  /*
    * Retorna uma promise com o valor da opção selecionada,
    * que será resolvida quando o backend devolver este dado.
    */
  async getValueAsync() {
    if (this._changePending) {
      return new Promise(accept => {
        this._valuePromiseCallbacks.push(accept);
      });
    }
    return Promise.resolve(this.value);
  }
  observeLabel() {
    if (this._textInput) {
      this._textInput.label = this.label;
    }
  }
  observeErrorMessage() {
    var _a;
    if (this._textInput) {
      this._textInput.errorMessage = this.errorMessage;
      if (!((_a = this.errorMessage) === null || _a === void 0 ? void 0 : _a.trim())) {
        this.setInputValue();
      }
    }
  }
  observeValue(newValue, oldValue) {
    if (this._textInput && newValue != oldValue) {
      this.handleNewValue(newValue, oldValue);
    }
    this._changePending = false;
  }
  observePrecision() {
    if (this._textInput) {
      this.setInputValue();
    }
  }
  handleNewValue(newValue, oldValue) {
    const newValueValidated = this.validateValue(newValue);
    const oldValueValidated = this.validateValue(oldValue);
    if (newValueValidated === null) {
      this._value = '';
    }
    if (newValueValidated === oldValueValidated) {
      return;
    }
    const textValue = this.getTextValue(newValueValidated) || '';
    const parsedNumber = this.getParsedNumber(textValue);
    if ((this._value || '') !== textValue && (parsedNumber !== undefined || !this._focused)) {
      this._value = textValue;
      this._focused = false;
      this.errorMessage = "";
    }
    const valueEmitted = newValueValidated === null ? undefined : newValueValidated;
    this.ezChange.emit(valueEmitted);
  }
  validateValue(value) {
    return isNaN(value) || value === undefined ? null : value;
  }
  getTextValue(value) {
    if (value == undefined)
      return undefined;
    let textValue = this.precision >= 0 ? core.NumberUtils.format(value.toString(), Number(this.precision), Number(this.prettyPrecision)) : value.toString();
    return (this.precision === 0) ? core.StringUtils.replaceAll(textValue, ".", "") : textValue;
  }
  changeValue(newValue) {
    this.errorMessage = "";
    if (this.value != newValue) {
      this.value = newValue === undefined ? null : newValue;
    }
    else {
      this.setInputValue();
      this.ezCancelWaitingChange.emit();
    }
  }
  setError(msg) {
    this.value = null;
    this.errorMessage = msg;
    this.ezCancelWaitingChange.emit();
  }
  handleBlur() {
    if (!this._changePending) {
      return;
    }
    try {
      const parsedNumber = this.getParsedNumber();
      if (parsedNumber !== undefined && isNaN(parsedNumber)) {
        this.setError(this.i18n("ez-number-input.invalidNumber"));
      }
      else {
        try {
          this.changeValue(parsedNumber);
        }
        catch (e) {
          this.setError(e.message);
          return;
        }
      }
    }
    finally {
      for (const callback of this._valuePromiseCallbacks) {
        callback(this.value);
      }
      this._valuePromiseCallbacks = [];
    }
  }
  handleInput() {
    const parsedNumber = this.getParsedNumber();
    if (parsedNumber !== this.value) {
      this._focused = true;
      this._changePending = true;
      this.ezStartChange.emit({ waitmessage: "", blocking: false });
    }
  }
  getParsedNumber(value = this._textInput.value) {
    return (value === null || value === void 0 ? void 0 : value.trim()) ? core.NumberUtils.stringToNumber(value) : undefined;
  }
  setInputValue() {
    const textValue = this.getTextValue(this.value) || '';
    if ((this._value || '') !== textValue) {
      this._value = textValue;
      this._textInput.value = this._value;
    }
  }
  async componentWillLoad() {
    this.i18n = await index$1.initI18n();
  }
  componentDidLoad() {
    CSSVarsUtils.CSSVarsUtils.applyVarsTextInput(this._elem, this._textInput);
    this.setInputValue();
    if (this.autoFocus) {
      requestAnimationFrame(() => {
        this.setFocus({ selectText: true });
      });
    }
  }
  render() {
    core.ElementIDUtils.addIDInfoIfNotExists(this._elem, 'input');
    let restrict = this.precision > 0 ? "0123456789,." : "0123456789";
    if (this.allowNegative) {
      restrict += '-';
    }
    return (index.h("ez-text-input", { class: "number__input", "data-element-id": core.ElementIDUtils.getInternalIDInfo("textInput"), ref: elem => this._textInput = elem, "data-slave-mode": "true", label: this.label, onBlur: () => this.handleBlur(), onInput: () => this.handleInput(), restrict: restrict, enabled: this.enabled, errorMessage: this.errorMessage, mode: this.mode, canShowError: this.canShowError, value: this._value, alternativePlaceholder: this.alternativePlaceholder }));
  }
  get _elem() { return index.getElement(this); }
  static get watchers() { return {
    "label": ["observeLabel"],
    "errorMessage": ["observeErrorMessage"],
    "value": ["observeValue"],
    "precision": ["observePrecision"],
    "prettyPrecision": ["observePrecision"]
  }; }
};
EzNumberInput.style = ezNumberInputCss;

exports.ez_number_input = EzNumberInput;
