import { test } from 'qunit';
import moduleForAcceptance from 'web-client/tests/helpers/module-for-acceptance';
import { stubLogin } from 'web-client/tests/helpers/stub-login';
import { openDatepicker } from 'ember-pikaday/helpers/pikaday';
import moment from 'moment';
import { BASE_URL } from 'web-client/mirage/routes/events';
import Test from 'ember-test';

moduleForAcceptance('Acceptance | dashboard/events', {
  beforeEach() {
    this.experiments.use({ ORC: 'yes' });
    let name = 'mitchlloyd';
    stubLogin({ login: name });
    this.channel = this.server.create('channel', { name });
  }
});

test('visiting the dashboard when not in the experiement group', function(assert) {
  assert.expect(1);

  this.experiments.use({ ORC: 'no' });

  // Just picking a page in the dashboard with no data setup needed
  visit(`/mitchlloyd/dashboard/steamkey`);

  andThen(() => {
    let eventsTab = find('[data-test-selector=events-tab]');
    assert.equal(eventsTab.length, 0, 'does not show the tab');
  });
});

test('directly visiting the events page when not in the experiment group', function(assert) {
  assert.expect(1);

  this.experiments.use({ ORC: 'no' });

  visit(`/mitchlloyd/dashboard/events`);

  andThen(() => {
    assert.equal(find('.ember_error_404').length, 1, 'renders the 404 page');
  });
});

test('visit events page when user has no events', function(assert) {
  assert.expect(1);

  this.experiments.use({ ORC: 'yes' });

  let url = `/mitchlloyd/dashboard/events`;

  visit(url);

  andThen(() => {
    assert.equal(find('[data-event-list]').children().length, 0, 'channel does not have any events');
  });
});

test('visit events page when user has two events', function(assert) {
  assert.expect(1);

  this.server.createList('event', 2, { channel: this.channel });
  let url = `/mitchlloyd/dashboard/events`;

  visit(url);

  andThen(() => {
    assert.equal(find('[data-event-list]').children().length, 2, 'channel two events');
  });
});

test('visit events page when the events index endpoint returns an error', function(assert) {
  assert.expect(2);
  let errorCount = 0;

  // Let us pass with test with an exception. See:
  //   https://github.com/emberjs/ember.js/issues/12791
  let originalExceptionHandler = Test.adapter.exception;
  Test.adapter.exception = () => errorCount++;

  let url = `/mitchlloyd/dashboard/events`;

  this.server.get(`${BASE_URL}/channels/${this.channel._id}/events`, {}, 500);

  visit(url);

  andThen(() => {
    assert.equal(find('[data-test-events-index-error]').length, 1, 'shows error message');
    assert.equal(errorCount, 1, 'throws one error');

    // Restore global exception handler
    Test.adapter.exception = originalExceptionHandler;
  });
});

test('delete an event', function(assert) {
  assert.expect(3);

  this.server.createList('event', 1, { channel: this.channel });
  let url = `/mitchlloyd/dashboard/events`;

  visit(url);

  andThen(() => {
    assert.equal(find('[data-event-list]').children().length, 1, 'channel has one event');
  });

  click('[data-test-delete]');

  andThen(() => {
    assert.equal(find('[data-event-list]').children().length, 0, 'the event has been deleted');
    assert.equal(this.server.schema.events.all().length, 0, 'event was removed from the backend');
  });
});

test('edit an event', function(assert) {
  assert.expect(2);

  this.server.create('event', 1, {
    channel: this.channel,
    title: 'My original event title'
  });

  let url = `/mitchlloyd/dashboard/events`;
  let newEventTitle = 'My new event title';

  visit(url);

  click('[data-test-edit]');
  fillIn('[data-title]', newEventTitle);
  click('[data-test-save]');

  andThen(() => {
    assert.equal(find('[data-event-title]').text().trim(), newEventTitle, 'the event has the new title');

    let event = this.server.schema.events.first();

    assert.equal(event.title, newEventTitle, 'new event title saved to server');
  });
});

test('cancel editing an event', function(assert) {
  assert.expect(2);

  let url = `/mitchlloyd/dashboard/events`;
  let oldEventTitle = 'My original event title';
  let newEventTitle = 'My new event title';

  this.server.create('event', {
    channel: this.channel,
    title: oldEventTitle
  });

  visit(url);

  click('[data-test-edit]');
  fillIn('[data-title]', newEventTitle);
  click('[data-test-cancel]');

  andThen(() => {
    assert.equal(find('[data-event-title]').text().trim(), oldEventTitle, 'the event title has not changed');

    let event = this.server.schema.events.first();

    assert.equal(event.title, oldEventTitle, 'new event title was not saved to server');
  });
});

test('creating an event', function(assert) {
  assert.expect(9);

  this.server.create('game', { name: 'League of Legends', _id: 1 });

  this.experiments.use({ ORC: 'yes' });

  let url = `/mitchlloyd/dashboard/events`;

  visit(url);
  click('[data-test-create-event]');

  andThen(() => {
    let startDateInput = find('[data-test-selector=start-date]')[0];
    openDatepicker(startDateInput).selectDate(new Date(2017, 0, 31));
  });

  fillIn('[data-test-selector=start-time]', '2:30pm');

  andThen(() => {
    let startDateInput = find('[data-test-selector=end-date]');
    openDatepicker(startDateInput).selectDate(new Date(2017, 1, 1));
  });

  fillIn('[data-test-selector=end-time]', '1:00am');

  fillIn('[data-title]', 'Event Title');
  fillIn('[data-test-selector=game-select]', 'League of Legends');
  fillIn('[data-description]', 'My great event');
  click('[data-test-save]');

  andThen(() => {
    let events = this.server.schema.events;
    assert.equal(events.all().models.length, 1, 'created one event');

    let event = events.first();
    assert.strictEqual(event.channel.id, this.channel.id, 'created on the right channel');

    assert.ok(moment(event.start_time).isSame('2017-01-31 14:30:00'), 'start time saved');
    assert.ok(moment(event.end_time).isSame('2017-02-01 01:00:00'), 'end time saved');
    assert.equal(event.title, 'Event Title', 'title saved');
    assert.equal(event.game_id, 1, 'game saved');
    assert.equal(event.description, 'My great event', 'description saved');

    assert.equal(find('[data-test-save]').length, 0, 'cannot find save button, create event form is hidden');
    assert.equal(find('[data-event-list]').children().length, 1, 'newly created event is visible');
  });
});
