import Component from 'ember-component';
import $ from 'jquery';
import { keyboardListener } from 'web-client/utilities/keyboard';
import inRange from 'web-client/utilities/in-range';
import isolateScrollListener from 'web-client/utilities/isolate-scroll-listener';

const ACTIVE_CLASS = 'isActive';
const SELECTABLE = '[data-ts_selectable]';

export default Component.extend({
  init() {
    this._super(...arguments);
    this._isKeyboardNavigating = false;
  },

  didInsertElement() {
    this._super(...arguments);

    this.addEventListener(...keyboardListener({
      down: this.activateNext,
      enter: this.selectActive,
      up: this.activatePrevious
    }));

    this.addEventListener(this.element, ...isolateScrollListener);
  },

  mouseOver(e) {
    if (this._isKeyboardNavigating) {
      return;
    }

    let selectable = $(e.target).closest(SELECTABLE, this.$());

    if (!selectable) {
      return;
    }

    this.activateElement(selectable);
  },

  mouseMove() {
    this._isKeyboardNavigating = false;
  },

  click(e) {
    // Clicking any tracked link in the panel will count as a click-through
    if ($(e.target).closest('a').attr('data-tt_content')) {
      this.get('onClickThrough')();
    }
  },

  shiftActive(e, shiftIndex) {
    e.preventDefault();
    this._isKeyboardNavigating = true;

    let searchElements = this.$(SELECTABLE);
    let activeElementIndex = searchElements.index(this.$(`.${ACTIVE_CLASS}`));
    let nextIndex = activeElementIndex + shiftIndex;

    if (inRange(nextIndex, 0, searchElements.length)) {
      let nextElement = searchElements.eq(nextIndex);
      this.activateElement(nextElement);
      this.scrollIntoView(nextElement);
    }
  },

  activateElement(element) {
    if (!element.hasClass(ACTIVE_CLASS)) {
      this.removeActive();
      element.addClass(ACTIVE_CLASS);
    }
  },

  removeActive() {
    let activeElement = this.$(`.${ACTIVE_CLASS}`);
    activeElement.removeClass(ACTIVE_CLASS);
  },

  activateNext(e) {
    this.shiftActive(e, 1);
  },

  activatePrevious(e) {
    this.shiftActive(e, -1);
  },

  selectActive(e) {
    e.preventDefault();
    let focusedElement = this.$(`.${ACTIVE_CLASS}`);
    if (focusedElement.length) {
      focusedElement.click();
    }
  },

  scrollIntoView(element) {
    let elementTop = element.offset().top;
    let elementBottom = elementTop + element.height();

    let panelTop = this.$().offset().top;
    let panelBottom = panelTop + this.$().height();

    let scrollTop = this.$().scrollTop();

    if (elementTop < panelTop) {
      this.$().scrollTop(scrollTop - (panelTop - elementTop));
    } else if (elementBottom > panelBottom) {
      this.$().scrollTop(scrollTop + (elementBottom - panelBottom));
    }
  }
});
