import { Utility } from '../../core/utility';
import { EventManager, EventWrapper, EVENT_TYPE } from '../../lib/event-manager/event-manager';

const REACTIVE_SUBMIT_BUTTON_INITIALIZED_CLASS = 'reactive-submit-button--initialized';

@Utility({
  selector: 'form',
})
export class ReactiveSubmitButton {

  _element;

  _requiredInputs;
  _submitButton;

  _eventManager;

  constructor(element) {
    if (!element) {
      throw new Error('Reactive Submit Button utility cannot be setup without an element!');
    }

    this._element = element;
    this._eventManager = new EventManager();

    if (this._element.classList.contains(REACTIVE_SUBMIT_BUTTON_INITIALIZED_CLASS)) {
      return false;
    }

    // abort if form has param data-formnorequired
    if (this._element.dataset.formnorequired !== undefined) {
      throw new Error('Form has formnorequired data attribute. Will skip setup of reactive submit button.');
    }

    this._requiredInputs = Array.from(this._element.querySelectorAll('[required]'));
    if (!this._requiredInputs) {
      // abort if form has no required inputs
      throw new Error('Submit button has formnorequired data attribute. Will skip setup of reactive submit button.');
    }

    const submitButtons = Array.from(this._element.querySelectorAll('[type="submit"]'));
    if (!submitButtons || !submitButtons.length) {
      throw new Error('Reactive Submit Button utility couldn\'t find any submit buttons!');
    }
    this._submitButton = submitButtons.reverse()[0];
    // abort if form has param data-formnorequired
    if (this._submitButton.dataset.formnorequired !== undefined) {
      return false;
    }

    this.setupInputs();
    this.updateButtonState();

    this._element.classList.add(REACTIVE_SUBMIT_BUTTON_INITIALIZED_CLASS);
  }

  destroy() {
    this._eventManager.removeAllEventListenersFromUtil();
    this._element.classList.remove(REACTIVE_SUBMIT_BUTTON_INITIALIZED_CLASS);
  }

  setupInputs() {
    this._requiredInputs.forEach((el) => {
      const checkbox = el.getAttribute('type') === 'checkbox';
      const eventType = checkbox ? EVENT_TYPE.CHANGE : EVENT_TYPE.INPUT;
      const valEvent = new EventWrapper(eventType,(() => {
        this.updateButtonState();
      }).bind(this), el );
      this._eventManager.registerNewListener(valEvent);
    });
  }

  updateButtonState() {
    if (this.inputsValid()) {
      this._submitButton.removeAttribute('disabled');
    } else {
      this._submitButton.setAttribute('disabled', 'true');
    }
  }

  inputsValid() {
    let done = true;
    this._requiredInputs.forEach((inp) => {
      const len = inp.value.trim().length;
      if (done && len === 0) {
        done = false;
      }
    });
    return done;
  }
}
