import moduleForComponent from 'web-client/tests/helpers/module-for-component';
import { test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import { KEY_CODES } from 'web-client/utilities/keyboard';

moduleForComponent('navigation-search/panel-content', 'Integration | Component | navigation-search/panel-content', {
  beforeEach() {
    this.render(hbs`
      {{#navigation-search/panel-content id="component-subject"}}
        <a data-ts_selectable="true">one</a>
        <a>skip-me</a>
        <a data-ts_selectable="true">two</a>
      {{/navigation-search/panel-content}}
    `);

    this.componentEl = this.$('#component-subject');
  }
});

test('activates items marked as selectable', function(assert) {
  assert.equal(activeItem(this.$()), '', 'nothing selected at first');
  triggerKey('down');
  assert.equal(activeItem(this.$()), 'one', 'selects next item');
  triggerKey('down');
  assert.equal(activeItem(this.$()), 'two', 'selects next item');
  triggerKey('down');
  assert.equal(activeItem(this.$()), 'two', 'stops at last item');
  triggerKey('up');
  assert.equal(activeItem(this.$()), 'one', 'selects previous item');
  triggerKey('up');
  assert.equal(activeItem(this.$()), 'one', 'stops at first item');
});

test('activates an item on mouseover only when the mouse moves', function(assert) {
  let coordinates1 = { x: 1, y: 1 };
  let coordinates2 = { x: 2, y: 2 };

  // In general mousemove fires after mouseover, but this is not the case in
  // IE. This test assumes the more complex scenario for our feature: where
  // mousemove fires first.
  triggerMouseEvent(this.componentEl, 'mousemove', coordinates1);
  triggerMouseEvent(this.$('a').last(), 'mouseover', coordinates1);

  assert.equal(activeItem(this.$()), 'two', 'selects next item');

  triggerKey('up');

  assert.equal(activeItem(this.$()), 'one', 'new item seleted');

  // Another mouseover event is triggered when the list in the panel scrolls.
  // However, the user has not actually moved their mouse cursor.
  triggerMouseEvent(this.$('a').last(), 'mouseover', coordinates1);
  assert.equal(activeItem(this.$()), 'one', 'first item remains active');

  // The user moves the mouse and causes a mouseover
  triggerMouseEvent(this.componentEl, 'mousemove', coordinates2);
  triggerMouseEvent(this.$('a').last(), 'mouseover', coordinates2);
  assert.equal(activeItem(this.$()), 'two', 'second item is active');
});

function triggerKey(keyCode) {
  let event = $.Event('keydown', { keyCode: KEY_CODES[keyCode] });
  $('body').trigger(event);
}

function triggerMouseEvent(element, eventName, coordinates) {
  let event = $.Event(eventName, {
    screenX: coordinates.x,
    screenY: coordinates.y
  });
  element.trigger(event);
}

function activeItem(element) {
  return element.find('.isActive').text().trim();
}
