this.ContextMenu = class {
  constructor(element, showContextMenuHandler, items = null, functionGetItems = null){
    this.element = element;
    this.showContextMenuHandler = showContextMenuHandler;
    this.items = items;
    this.functionGetItems = functionGetItems;

    this.init();
  }

  getPosition(e) {
    let x = 0;
    let y = 0;

    if (e.pageX || e.pageY) {
      x = e.pageX;
      y = e.pageY;
    } else if (e.clientX || e.clientY) {
      x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
      y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
    }

    return {x, y};
  }

  getContextMenuItem(name, icon, handler, disabled = false){
    const li = $(`<li>`);
    const a = $('<a>');
    const span = $(`<span class="uk-margin-small-right" uk-icon="icon: ${icon}"></span>`);

    if(disabled) li.addClass('uk-disabled');

    a.append(span, i18n.tr(name));
    li.append(a);

    li.on('click', e => {
      e.preventDefault();
      e.target.blur();
      if(handler) handler();
    });

    return li;
  }

  positionMenu(contextMenu, e) {
    const clickCoords = this.getPosition(e);
    const clickCoordsX = clickCoords.x;
    const clickCoordsY = clickCoords.y;
    const menuWidth = contextMenu.width() + 4;
    const menuHeight = 380;
    const windowWidth = window.innerWidth;
    const windowHeight = window.innerHeight;

    let left = 0;
    let top = 0;

    if ( (windowWidth - clickCoordsX) < menuWidth ) {
      left = windowWidth - menuWidth;
    } else {
      left = clickCoordsX;
    }

    if ( (windowHeight - clickCoordsY) < menuHeight ) {
      top = windowHeight - menuHeight;
    } else {
      top = clickCoordsY;
    }

    contextMenu.css({
      "left": left + "px",
      "top": top + "px"
    });
  }

  renderContextMenu(event){
    const contextMenu = $('<div>', {class: 'custom_contextmenu'});
    const nav = $('<ul class="uk-nav-default uk-nav-parent-icon" uk-nav>');

    contextMenu.append(nav);

    this.items.forEach(item => {
      if(item == 'divider') {
        nav.append('<li class="uk-nav-divider"></li>');
      } else {
        const {name, icon, handler, disabled = false} = item;
        nav.append(this.getContextMenuItem(name, icon, () => handler(), disabled));
      }
    });

    $('body').append(contextMenu);
    this.positionMenu(contextMenu, event);

    if(this.showContextMenuHandler) this.showContextMenuHandler();

    contextMenu.show('fast');
  }

  init(){
    this.element.on('contextmenu', event => {
      event.preventDefault();

      $('.custom_contextmenu').remove();

      if(this.functionGetItems && typeof this.functionGetItems == 'function') {
        Cons.showLoader();
        this.functionGetItems().then(items => {
          Cons.hideLoader();
          this.items = items;
          this.renderContextMenu(event);
        });
      } else {
        this.renderContextMenu(event);
      }

      return false;
    });
  }
}

$(document).off()
.on('contextmenu', () => $('.custom_contextmenu').remove())
.on('click', () => $('.custom_contextmenu').remove());
