import { test } from 'ember-qunit';
import moduleForComponent from 'web-client/tests/helpers/module-for-component';
import hbs from 'htmlbars-inline-precompile';
import wait from 'ember-test-helpers/wait';
import { isBlank } from 'ember-utils';
import { ARCHIVE_TYPE_PARAM } from 'web-client/utilities/video/types';
import { stubLogin, stubLogout } from 'web-client/tests/helpers/stub-login';

const USER_NAME = 'twitch';
const NOT_FOLLOWING_CHANNEL_NAME = 'day9tv';
const FOLLOWING_CHANNEL_NAME = 'destiny';

const UNFOLLOW_BUTTON_SELECTOR = `.${FOLLOWING_CHANNEL_NAME} .follow-button`;
const FOLLOW_BUTTON_SELECTOR = `.${NOT_FOLLOWING_CHANNEL_NAME} .follow-button`;

moduleForComponent('follow-button', 'Integration | Component | follow-button', {
  beforeEach() {
    // We use this rather than the session mock because the component makes
    // a call to the store and needs the user's cookie
    stubLogin({ login: USER_NAME });
    this.inject.service('session');

    return this.session.initializeSession().then(() => {
      this.set(NOT_FOLLOWING_CHANNEL_NAME, { id: NOT_FOLLOWING_CHANNEL_NAME, game: 'cs' });
      this.set(FOLLOWING_CHANNEL_NAME, { id: FOLLOWING_CHANNEL_NAME, game: 'cs' });

      let channel = this.server.create('channel', { name: FOLLOWING_CHANNEL_NAME });
      this.server.create('follow', { userName: USER_NAME, channelName: FOLLOWING_CHANNEL_NAME, channel });

      this.defaultTemplate = hbs`
        <div class="day9tv">
          {{follow-button channel=day9tv}}
        </div>

        <div class="destiny">
          {{follow-button channel=destiny}}
        </div>
      `;
    });
  },
  afterEach() {
    stubLogout();
  }
});

test('following', function(assert) {
  assert.expect(3);
  let done = assert.async();
  let $button;

  this.render(this.defaultTemplate);

  return wait().then(() => {
    $button = this.$(FOLLOW_BUTTON_SELECTOR);
    assert.strictEqual($button.hasClass('is-following'), false, 'button initially not following');
    $button.click();

    return wait();
  }).then(() => {
    assert.ok($button.hasClass('is-following'), 'button changes to is-following');
    let newFollow = this.server.db.follows.where({ userName: USER_NAME, channelName: NOT_FOLLOWING_CHANNEL_NAME })[0];
    assert.ok(newFollow, 'follow added via API');
    done();
  });
});

test('unfollowing', function(assert) {
  assert.expect(3);
  let done = assert.async();
  let $button;

  this.render(this.defaultTemplate);
  return wait().then(() => {
    $button = this.$(UNFOLLOW_BUTTON_SELECTOR);
    assert.strictEqual($button.hasClass('is-following'), true, 'button initially following');
    $button.click();

    return wait();
  }).then(() => {
    assert.strictEqual($button.hasClass('is-following'), false, 'button changes to not following');

    let newFollow = this.server.db.follows.where({ userName: USER_NAME, channelName: FOLLOWING_CHANNEL_NAME })[0];
    assert.notOk(newFollow, 'follow deleted via API');

    done();
  });
});

test('followed button styles', function(assert) {
  assert.expect(4);
  let done = assert.async();

  this.render(this.defaultTemplate);
  return wait().then(() => {
    let $button = this.$(UNFOLLOW_BUTTON_SELECTOR);
    assert.ok($button.hasClass('is-initialized'), '.is-initialized');
    assert.ok($button.hasClass('is-following'), '.is-following');

    assert.notStrictEqual(this.$('.svg-heart').css('display'), 'none', 'displaying svg heart');
    assert.ok(isBlank(this.$('.follow-button:last').text()), 'link has no text');
    done();
  });
});

test('unfollowed button styles', function(assert) {
  assert.expect(4);
  let done = assert.async();

  this.render(this.defaultTemplate);
  return wait().then(() => {
    let $button = this.$(FOLLOW_BUTTON_SELECTOR);
    assert.ok($button.hasClass('is-initialized'), '.is-initialized');
    assert.strictEqual($button.hasClass('is-following'), false, ':not(.is-following)');

    assert.notStrictEqual(this.$('.svg-heart').css('display'), 'none', 'showing svg heart');
    assert.equal(this.$('.follow-button:first').text().trim(), 'Follow', 'link says "Follow"');
    done();
  });
});

test('following metric', function(assert) {
  assert.expect(3);
  let done = assert.async();

  this.on('track', (event, channel, data) => {
    assert.equal(event, 'follow', 'follow event tracked');
    assert.deepEqual(channel, this.get(NOT_FOLLOWING_CHANNEL_NAME), 'passed channel to tracker');
    assert.deepEqual(data, {
      channel: NOT_FOLLOWING_CHANNEL_NAME,
      game: 'cs',
      src: 'chat',
      notifications: false,
      vod_id: null,
      vod_type: null
    }, 'data passed to tracker');

    done();
  });

  this.render(hbs`
    <div class="day9tv">
      {{follow-button channel=day9tv name='chat' track=(action 'track')}}
    </div>
  `);

  return wait().then(() => {
    this.$(FOLLOW_BUTTON_SELECTOR).click();
  });
});

test('unfollowing metric', function(assert) {
  assert.expect(3);
  let done = assert.async();

  this.on('track', (event, channel, data) => {
    assert.equal(event, 'unfollow', 'follow event tracked');
    assert.deepEqual(channel, this.get(FOLLOWING_CHANNEL_NAME), 'passed channel to tracker');
    assert.deepEqual(data, {
      channel: FOLLOWING_CHANNEL_NAME,
      game: 'cs',
      src: 'chat',
      notifications: false,
      vod_id: null,
      vod_type: null
    }, 'data passed to tracker');

    done();
  });

  this.render(hbs`
    <div class="destiny">
      {{follow-button channel=destiny name='chat' track=(action 'track')}}
    </div>
  `);

  return wait().then(() => {
    this.$(UNFOLLOW_BUTTON_SELECTOR).click();
  });
});

test('traccking events include vodId and vodType', function(assert) {
  assert.expect(3);
  let done = assert.async();

  this.on('track', (event, channel, data) => {
    assert.equal(event, 'follow', 'follow event tracked');
    assert.deepEqual(channel, this.get(NOT_FOLLOWING_CHANNEL_NAME), 'passed channel to tracker');
    assert.deepEqual(data, {
      channel: NOT_FOLLOWING_CHANNEL_NAME,
      game: 'cs',
      src: 'chat',
      notifications: false,
      vod_id: 'v123456',
      vod_type: ARCHIVE_TYPE_PARAM
    }, 'data passed to tracker');

    done();
  });

  this.render(hbs`
    <div class="day9tv">
      {{follow-button
        channel=day9tv
        name='chat'
        track=(action 'track')
        vodId='v123456'
        vodType='archive'
      }}
    </div>
  `);

  return wait().then(() => {
    this.$(FOLLOW_BUTTON_SELECTOR).click();
  });
});
