import $ from 'domtastic';
import Popper from 'popper.js';
import ToggleComponent from '../_helpers/toggleComponent';

export default class Dropdown extends ToggleComponent {
  constructor(element, customOptions) {
    const $dropdown = $(element);

    let options = {
      target: `[data-sui-o-dropdown="${$dropdown.attr('id')}"]`,
      dataAttrBase: 'data-sui-o-dropdown',
      clickOutsideEnabled: true,
      focusRecoverEnabled: true,
      placement: 'bottom-start',
      itemClass: 'sui-o-dropdown__link',
      itemDisabledClass: 'as--disabled',
      itemSelectedClass: 'as--selected',
    };

    // Merge custom options
    if (customOptions) {
      options = $.extend({}, options, customOptions);
    }

    super($dropdown, options);
  }

  _onDestroy() {
    super._onDestroy();

    if (this.popper) {
      this.popper.destroy();
    }
  }

  _onOpen(clickedElement) {
    this.selectedItem = -1;

    const $target = clickedElement ? $(clickedElement) : $(this.options.target);
    const $dropdown = this.$component;

    if (this.popper) {
      this.popper.destroy();
    }

    if ($target && $target[0] && $dropdown && $dropdown[0]) {
      this.popper = new Popper($target[0], $dropdown[0], {
        placement: this.options.placement,
      });
    }

    super._onOpen();
  }

  _onClose() {
    super._onClose();

    this._unselectItems();
  }

  _focusElement(element) {
    const $target = $(element).first();
    if ($target && $target[0]) {
      $target[0].focus();
    }
  }

  _keysMethods(event) {
    super._keysMethods(event);

    // Arrow up
    if (event.which === 38) {
      event.preventDefault();
      this._prevItem();
    }

    // Arrow down
    if (event.which === 40) {
      event.preventDefault();
      this._nextItem();
    }
  }

  _getItems() {
    return $(`.${this.options.itemClass}:not(:disabled):not(.${this.options.itemDisabledClass})`, this.$component);
  }

  _nextItem() {
    const indexMax = this._getItems().length - 1;
    if (this.selectedItem >= indexMax) {
      this._selectItem(indexMax);
      return;
    }

    this.selectedItem = parseInt(this.selectedItem, 10) + 1;
    this._selectItem(this.selectedItem);
  }

  _prevItem() {
    if (this.selectedItem <= 0) {
      this._selectItem(0);
      return;
    }

    this.selectedItem = parseInt(this.selectedItem, 10) - 1;
    this._selectItem(this.selectedItem);
  }

  _selectItem(index) {
    this._unselectItems();
    const $item = $(this._getItems()[index]);
    $item.addClass(this.options.itemSelectedClass);
    this._focusElement($item);
  }

  _unselectItems() {
    const $items = this._getItems();
    $items.removeClass(this.options.itemSelectedClass);
  }
}
