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

const PASSWORD_INITIALIZED_CLASS = 'password-input--initialized';

@Utility({
  selector: 'input[type="password"]:not([uw-no-password])',
})
export class Password {
  _element;
  _iconEl;
  _toggleContainerEl;
  _wrapperEl;

  _eventManager;
  
  constructor(element) {
    if (!element)
      throw new Error('Password utility cannot be setup without an element!');

    if (element.classList.contains(PASSWORD_INITIALIZED_CLASS))
      return false;

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

    this._element.classList.add('password-input__input');

    const siblingEl = this._element.nextSibling;
    const parentEl = this._element.parentElement;

    this._wrapperEl = document.createElement('div');
    this._wrapperEl.classList.add('password-input__wrapper');
    this._wrapperEl.appendChild(this._element);

    this._toggleContainerEl = document.createElement('div');
    this._toggleContainerEl.classList.add('password-input__toggle');
    this._wrapperEl.appendChild(this._toggleContainerEl);

    this._iconEl = document.createElement('i');
    this._iconEl.classList.add('fas', 'fa-fw');
    this._toggleContainerEl.appendChild(this._iconEl);

    parentEl.insertBefore(this._wrapperEl, siblingEl);

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

  start() {
    this.updateVisibleIcon(this.isVisible());

    const mouseOverEv = new EventWrapper(EVENT_TYPE.MOUSE_OVER, (() => {
      this.updateVisibleIcon(!this.isVisible());
    }).bind(this), this._toggleContainerEl);

    const mouseOutEv = new EventWrapper(EVENT_TYPE.MOUSE_OUT, (() => {
      this.updateVisibleIcon(this.isVisible());
    }).bind(this), this._toggleContainerEl);

    const clickEv = new EventWrapper(EVENT_TYPE.CLICK, ((event) => {
      event.preventDefault();
      event.stopPropagation();
      this.setVisible(!this.isVisible());
    }).bind(this), this._toggleContainerEl );

    this._eventManager.registerListeners([mouseOverEv, mouseOutEv, clickEv]);
  }

  destroy() {
    this._eventManager.cleanUp();
    this._iconEl.remove();
    this._toggleContainerEl.remove();
    this._wrapperEl.remove();
    this._iconEl.remove();

    this._element.classList.remove(PASSWORD_INITIALIZED_CLASS);
  }

  isVisible() {
    return this._element.type !== 'password';
  }

  setVisible(visible) {
    this._element.type = visible ? 'text' : 'password';
    this.updateVisibleIcon(visible);
  }

  updateVisibleIcon(visible) {
    function visibleClass(visible) {
      return 'fa-' + (visible ? 'eye' : 'eye-slash');
    }

    this._iconEl.classList.remove(visibleClass(!visible));
    this._iconEl.classList.add(visibleClass(!!visible));
  }
}
