import { test } from 'qunit';

import moduleForAcceptance from 'web-client/tests/helpers/module-for-acceptance';
import { stubLogin } from 'web-client/tests/helpers/stub-login';
import { EXPERIMENT_NAME, PERPETUA_ALLOW_GROUP } from 'web-client/utilities/video/playlist';
import PlaylistManagerEditPage from 'web-client/tests/pages/manager/playlists/edit';
import playlistScenario from 'web-client/mirage/scenarios/video-playlist';

moduleForAcceptance('Acceptance | /manager/collections/<id> (edit)', {
  beforeEach() {
    this.experiments.use({ [EXPERIMENT_NAME]: PERPETUA_ALLOW_GROUP[0] }); // multiple opt-in groups exist--choose first
    stubLogin();
    this.collection = playlistScenario(this.server, { itemCount: 3 });
    this.page = PlaylistManagerEditPage.create({
      id: this.collection.id
    });
    $('#ember-testing').css({
      zoom: '100%'
    });
  }
});

test('visiting the edit page', function(assert) {
  assert.expect(3);

  visit(this.page.url());

  andThen(() => {
    assert.equal(currentURL(), `/twitch/manager/collections/${this.collection.id}`);
    assert.equal(currentRouteName(), 'manager.collections.edit');

    assert.elementCount(
      this.page.items(),
      this.collection.items.models.length,
      'should properly display collection items'
    );
  });
});

test('clicking the All Collections button', function(assert) {
  assert.expect(2);

  visit(this.page.url());
  click(this.page.get('allCollectionsSelector'));

  andThen(() => {
    assert.equal(currentURL(), '/twitch/manager/collections');
    assert.equal(currentRouteName(), 'manager.collections.index');
  });
});

test('dragging and dropping the first row', function(assert) {
  assert.expect(1);
  let itemNames = this.collection.items.models.map(item => item.title);
  let expectedPositions = [itemNames[1], itemNames[0], itemNames[2]];

  visit(this.page.url());

  andThen(() => {
    this.page.close_nav();
    this.page.scrollDown();
    this.page.forceHandleDisplay();
  });

  andThen(() => {
    const handleX = this.page.rowEnd() - 15;

    const rowHeight = this.page.rowHeight();
    const crossDownwardCenter = rowHeight/2 + 20;
    this.page.scrollDown();

    triggerEvent(this.page.firstHandleSelector(), 'mousedown', { clientX: 0, clientY: 0 });
    let secondRowPosition = this.page.firstHandleTop() + rowHeight + crossDownwardCenter;
    triggerEvent(this.page.firstHandleSelector(), 'mousemove', { clientX: handleX, clientY: secondRowPosition });
    triggerEvent(this.page.firstHandleSelector(), 'mouseup', { clientX: handleX, clientY: secondRowPosition });
    // result: ["item 2", "item 1", "item 3"]
  });

  andThen(() => {
    assert.deepEqual(this.page.itemNames(), expectedPositions, 'should swap items 1 and 2');
  });
});

test('dragging and dropping the last row', function(assert) {
  assert.expect(1);
  let itemNames = this.collection.items.models.map(item => item.title);
  let expectedPositions = [itemNames[0], itemNames[2], itemNames[1]];

  visit(this.page.url());

  andThen(() => {
    this.page.close_nav();
    this.page.scrollDown();
    this.page.forceHandleDisplay();
  });

  andThen(() => {
    const handleX = this.page.rowEnd() - 15;

    const rowHeight = this.page.rowHeight();
    const crossUpwardCenter = rowHeight/2 - 20;
    this.page.scrollDown();

    triggerEvent(this.page.lastHandleSelector(), 'mousedown', { clientX: 0, clientY: 0 });
    let firstRowPosition = this.page.lastHandleTop() - rowHeight + crossUpwardCenter;
    triggerEvent(this.page.lastHandleSelector(), 'mousemove', { clientX: handleX, clientY: firstRowPosition });
    triggerEvent(this.page.lastHandleSelector(), 'mouseup', { clientX: handleX, clientY: firstRowPosition });
    // result: ["item 1", "item 3", "item 2"]
  });

  andThen(() => {
    assert.deepEqual(this.page.itemNames(), expectedPositions, 'should swap items 2 and 3');
  });
});

test('dragging and dropping multiple rows', function(assert) {
  assert.expect(3);
  let itemNames = this.collection.items.models.map(item => item.title);
  let expectedPositions = [itemNames[2], itemNames[1], itemNames[0]];
  visit(this.page.url());

  andThen(() => {
    this.page.close_nav();
    this.page.scrollDown();
    this.page.forceHandleDisplay();
  });

  andThen(() => {
    const handleX = this.page.rowEnd() - 15;

    const rowHeight = this.page.rowHeight();
    const crossDownwardCenter = rowHeight/2 + 20;
    const crossUpwardCenter = rowHeight/2 - 20;

    // Move item at index 0 to index 1
    triggerEvent(this.page.firstHandleSelector(), 'mousedown', { clientX: 0, clientY: 0 });
    let secondRowPosition = this.page.firstHandleTop() + rowHeight + crossDownwardCenter;
    triggerEvent(this.page.firstHandleSelector(), 'mousemove', { clientX: handleX, clientY: secondRowPosition });
    triggerEvent(this.page.firstHandleSelector(), 'mouseup', { clientX: handleX, clientY: secondRowPosition });
    // result: ["item 2", "item 1", "item 3"]

    triggerEvent(this.page.lastHandleSelector(), 'mousedown', { clientX: 0, clientY: 0 });
    let firstRowPosition = this.page.lastHandleTop() - (2 * rowHeight) + crossUpwardCenter;
    triggerEvent(this.page.lastHandleSelector(), 'mousemove', { clientX: handleX, clientY: firstRowPosition });
    triggerEvent(this.page.lastHandleSelector(), 'mouseup', { clientX: handleX, clientY: firstRowPosition });
    // result: ["item 3", "item 2", "item 1"]
  });

  andThen(() => {
    this.page.itemNames().forEach((item, index) => {
      assert.equal(item, expectedPositions[index], `items at index ${index} did not match`);
    });
  });
});
