import { test } from 'qunit';
import moduleForAcceptance from 'web-client/tests/helpers/module-for-acceptance';
import { stubLogin } from 'web-client/tests/helpers/stub-login';
import { stubTMI, restoreTMI } from 'web-client/tests/helpers/stub-tmi';
import WhisperPage from 'web-client/tests/pages/whisper';
import whisperScenario from 'web-client/mirage/scenarios/whisper';
import channelScenario from 'web-client/mirage/scenarios/channel';

import Ember from 'ember';

const { getProperties } = Ember;

// const stubUser = { id: 12345, username: 'twitch' };

moduleForAcceptance('Acceptance | whisper', {
  beforeEach() {
    this.page = WhisperPage.create();
    stubTMI(this);
    this.user = stubLogin({ login: 'twitch' });
    channelScenario(this.server, 'twitch');
  },
  afterEach() {
    restoreTMI(this);
  }
});

test('visiting /whisper', function(assert) {
  assert.expect(3);
  whisperScenario(this.server, { user: this.user });
  visit(this.page.url());

  andThen(() => {
    assert.ok(this.page.hasUnread(), 'unread icon');
  });

  click(this.page.icon());

  andThen(() => {
    assert.ok(this.page.hasSenderName(), 'sender name');
    assert.ok(this.page.hasMessagePreview(), 'message preview');
  });
});

test('sending whisper chat on existing thread', function(assert) {
  assert.expect(5);

  whisperScenario(this.server, { user: this.user });

  visit(this.page.url());

  click(this.page.icon());

  this.page.fillInSearch('friend');

  andThen(() => {
    assert.ok(this.page.searchResult('friend'));

    click(this.page.searchResultSelector('friend'));
  });

  let message = 'hello again';
  andThen(() => {
    assert.equal(this.server.db.messages.length, 0, 'sanity check mirage messages start empty');
    this.page.fillInChat(message);
  });

  andThen(() => {
    let lastMessage = this.server.db.messages[0];
    assert.ok(lastMessage, 'messages posted to API');
    assert.deepEqual(getProperties(lastMessage, 'body' , 'from_id', 'to_id'), {
      body: message,
      from_id: 12345,
      to_id: 456
    }, 'message body, from_id, and to_id posted to API');
    assert.ok(this.page.hasMessage(message));
  });
});

test('sending whisper chat to a user with no existing thread', function(assert) {
  assert.expect(5);

  whisperScenario(this.server, { existingThread: false, user: this.user });

  visit(this.page.url());

  click(this.page.icon());

  this.page.fillInSearch('friend');

  andThen(() => {
    assert.ok(this.page.searchResult('friend'));

    click(this.page.searchResultSelector('friend'));
  });

  let message = 'hello again';

  andThen(() => {
    assert.equal(this.server.db.messages.length, 0, 'sanity check mirage messages start empty');
    this.page.fillInChat(message);
  });

  andThen(() => {
    let lastMessage = this.server.db.messages[0];
    assert.ok(lastMessage, 'messages posted to API');
    assert.deepEqual(getProperties(lastMessage, 'body' , 'from_id', 'to_id'), {
      body: message,
      from_id: 12345,
      to_id: 456
    }, 'message body, from_id, and to_id posted to API');
    assert.ok(this.page.hasMessage(message));
  });
});

test('emoticon filter stays focused when clicked', function(assert) {
  assert.expect(2);

  let done = assert.async();

  whisperScenario(this.server, { existingThread: false, user: this.user });

  visit(this.page.url());

  click(this.page.icon());

  this.page.fillInSearch('friend');

  andThen(() => {
    assert.ok(this.page.searchResult('friend'));
  });

  click(this.page.searchResultSelector('friend'));

  click(this.page.emoticonSelectorToggle());

  andThen(() => {
    // TODO: determine why focus cannot be detected synchronously in this case
    $(document).one('focus', this.page.emoticonFilter(), () => {
      assert.ok(true, "emoticon filter input remains focused on click");
      done();
    });

    click(this.page.emoticonFilter());
  });
});
