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

moduleForComponent('video/preview-card', 'Integration | Component | video/preview-card', {
  beforeEach() {
    this.set('fakeVideo', {
      url: '/bacon_donut/v/55296210',
      preview: '/some-preview-img.png',
      views: 100,
      length: 1000,
      recordedDate: '2016-03-19T21:55:58Z',
      game: 'Creative',
      gameUrl: '/directory/game/Creative',
      title: 'Awesome Title!',
      description: 'Some video description',
      channel: {
        name: 'rwjblue',
        display_name: 'rwjblue'
      }
    });

    this.routeActionInvocations = [];
    this.owner.register('helper:route-action', helper(([...args]) => {
      return (...invocationArgs) => {
        this.routeActionInvocations.push(args.concat(invocationArgs));
      };
    }));
  }
});

test('clicking stream thumbnail triggers route transition', function (assert) {
  this.render(hbs`{{video/preview-card video=fakeVideo}}`);

  this.$('a.cap').click();

  let routeActionInvocation = this.routeActionInvocations[0];
  assert.equal(routeActionInvocation[0], 'handleVideoClick');
  assert.equal(routeActionInvocation[1], this.get('fakeVideo'));
});

test('displays formatted viewer count', function (assert) {
  this.set('fakeVideo.viewers', 12345);
  this.render(hbs`{{video/preview-card video=fakeVideo}}`);

  let infoText = this.$('.info').text().trim();
  infoText = infoText.replace(/\s+/g, ' ');

  assert.equal(infoText, 'Some video description Mar 19, 2016 · rwjblue');
});

test('displays video title when present', function (assert) {
  this.set('fakeVideo.title', 'Do EEEEETTT!!');
  this.render(hbs`{{video/preview-card video=fakeVideo}}`);

  let titleText = this.$('.title').text().trim();

  assert.equal(titleText, this.get('fakeVideo.title'));
});

test('displays tags when showTags is true', function (assert) {
  this.set('fakeVideo.tags', [{ tag: 'gamedev', id: 'gamedev' }, { tag: 'programming', id: 'programming' }]);
  this.set('showTags', true);
  this.render(hbs`{{video/preview-card video=fakeVideo showTags=showTags}}`);

  assert.equal(this.$('.ct-tag').length, 0);
});

test('does not display tags when showTags is false', function (assert) {
  this.set('fakeVideo.tags', [{ tag: 'gamedev', id: 'gamedev' }, { tag: 'programming', id: 'programming' }]);
  this.set('showTags', false);
  this.render(hbs`{{video/preview-card video=fakeVideo showTags=showTags}}`);

  assert.equal(this.$('.ct-tag').length, 0);
});

test('does not display tags when showTags is not provided', function (assert) {
  this.set('fakeVideo.tags', [{ tag: 'gamedev', id: 'gamedev' }, { tag: 'programming', id: 'programming' }]);
  this.render(hbs`{{video/preview-card video=fakeVideo}}`);

  assert.equal(this.$('.ct-tag').length, 0);
});


test('when a video is more than 24 hours old', function (assert) {
  this.render(hbs`{{video/preview-card video=fakeVideo}}`);
  let dateString = moment(this.get('fakeVideo.recordedDate')).format('MMM D, YYYY');
  let infoText = this.$('.info').text().trim();
  let startIndex = infoText.indexOf(dateString);
  let infoDate = infoText.substring(startIndex, startIndex + dateString.length);

  assert.equal(dateString, 'Mar 19, 2016', 'timestamp shown is Mar 19, 2016');
  assert.equal(infoDate, dateString, 'should display an absolute time');
});

test('when a co-view video is less than 14 days old', function (assert) {
  let twoWeeksAgo = moment().subtract(13, 'days').toISOString();
  this.set('fakeVideo.recordedDate', twoWeeksAgo);
  this.render(hbs`{{video/preview-card video=fakeVideo isCoview=true}}`);
  let dateString = moment(twoWeeksAgo).fromNow();
  let infoText = this.$('.info').text().trim();
  let startIndex = infoText.indexOf(dateString);
  let infoDate = infoText.substring(startIndex, startIndex + dateString.length);

  assert.equal(dateString, '13 days ago', 'timestamp shown is 13 days ago');
  assert.equal(infoDate, dateString, 'should display a relative time within 14 days');
});
