import Ember from 'ember';
import { moduleForComponent, test } from 'ember-qunit';
import Helper from 'ember-helper';
import { EMOTICONS_V1_URL } from 'web-client/utilities/urls/static-cdn';
const { run } = Ember;

moduleForComponent('twitch-feed/story-card-body', 'Unit | Component | story card body', {
  unit: true,
  needs: [],
  setup() {
    this.register('helper:i18n', Helper.helper(([value]) => value));
  }
});

test('Simple Strings are Passed Through', function(assert) {
  assert.expect(2);
  let result = this.subject({body: 'Hello There'});

  assert.equal(this.$().text().trim(), 'Hello There');
  assert.ok(result);
});

test('Passed in emotes are replaced', function(assert) {
  assert.expect(3);
  this.subject({
    body: 'Hello there Keepo',
    emotes: [
      {
        start: 12,
        end: 17,
        id: 1902
      }
    ]
  });

  let emoticons = this.$('.js-emoticon');
  assert.equal(emoticons.length, 1, 'Correct number of emoticon elements added');
  let keepo = emoticons[0];
  assert.equal(keepo.alt, 'Keepo', "Alt text matches the emote's text as typed");
  assert.equal(keepo.src, `${EMOTICONS_V1_URL}/1902/1.0`);
});

test('Emotes have expected tooltip annotations', function(assert) {
  assert.expect(2);
  this.subject({
    body: 'Hello there Keepo',
    emotes: [
      {
        start: 12,
        end: 16,
        id: 1902
      }
    ]
  });

  let keepo = this.$('.js-emoticon')[0];
  assert.equal(keepo.title, 'Keepo', "Title matches the emote's text as typed");
  assert.ok(keepo.classList.contains('tooltip'), 'Tooltip class is present');
});

test('Multiple passed in emotes are replaced', function(assert) {
  assert.expect(7);
  this.subject({
    body: 'Hello there Keepo Kappa Keepo',
    emotes: [
      {
        start: 12,
        end: 16,
        id: 1902
      },
      {
        start: 18,
        end: 22,
        id: 25
      },
      {
        start: 24,
        end: 28,
        id: 1902
      }
    ]
  });

  let emoticons = this.$('.js-emoticon');
  assert.equal(emoticons.length, 3, 'Correct number of emoticon elements added');

  let keepo = emoticons[0];
  assert.equal(keepo.alt, 'Keepo', "Alt text matches the emote's text as typed");
  assert.equal(keepo.src, `${EMOTICONS_V1_URL}/1902/1.0`);

  let kappa = emoticons[1];
  assert.equal(kappa.alt, 'Kappa', "Alt text matches the emote's text as typed");
  assert.equal(kappa.src, `${EMOTICONS_V1_URL}/25/1.0`);

  keepo = emoticons[2];
  assert.equal(keepo.alt, 'Keepo', "Alt text matches the emote's text as typed");
  assert.equal(keepo.src, `${EMOTICONS_V1_URL}/1902/1.0`);
});

test('Strings with links are detected', function(assert) {
  assert.expect(6);
  let result = this.subject({body: 'This message contains a link https://www.twitch.tv'});
  assert.ok(result);

  assert.equal(this.$().text().trim(), 'This message contains a link https://www.twitch.tv');

  let urls = this.$('.js-feedlink');
  assert.equal(urls.length, 1, 'Correct number of link elements added');

  let twitchUrl = urls[0];
  assert.equal(twitchUrl.href, 'https://www.twitch.tv/', 'URL for link properly parsed from text');
  assert.equal(twitchUrl.innerText, 'https://www.twitch.tv', 'Link text is reproduced as typed');
  assert.equal(twitchUrl.target, '_blank', 'Link will open in new tab/window');
});

test('Strings with links with no protocol are detected', function(assert) {
  assert.expect(2);
  this.subject({body: 'This message contains a minimal link twitch.tv/twitch'});

  let urls = this.$('.js-feedlink');
  let twitchUrl = urls[0];
  assert.equal(twitchUrl.href, 'http://twitch.tv/twitch', 'URL for link properly parsed from text');
  assert.equal(twitchUrl.innerText, 'twitch.tv/twitch', 'Link text is reproduced as typed');
});

test('Strings with multiple links are detected', function(assert) {
  assert.expect(7);
  this.subject({body: 'This message contains some links https://www.twitch.tv some text and http://www.google.com'});

  let urls = this.$('.js-feedlink');
  assert.equal(urls.length, 2, 'Correct number of link elements added');

  let twitchUrl = urls[0];
  assert.equal(twitchUrl.href, 'https://www.twitch.tv/', 'URL for link properly parsed from text');
  assert.equal(twitchUrl.innerText, 'https://www.twitch.tv', 'Link text is reproduced as typed');
  assert.equal(twitchUrl.target, '_blank', 'Link will open in new tab/window');

  let googleUrl = urls[1];
  assert.equal(googleUrl.href, 'http://www.google.com/', 'URL for link properly parsed from text');
  assert.equal(googleUrl.innerText, 'http://www.google.com', 'Link text is reproduced as typed');
  assert.equal(googleUrl.target, '_blank', 'Link will open in new tab/window');
});

test('Strings with links in the middle are detected', function(assert) {
  assert.expect(4);
  this.subject({body: 'This message contains a link https://www.twitch.tv and following text'});

  let urls = this.$('.js-feedlink');
  assert.equal(urls.length, 1, 'Correct number of link elements added');

  let twitchUrl = urls[0];
  assert.equal(twitchUrl.href, 'https://www.twitch.tv/', 'URL for link properly parsed from text');
  assert.equal(twitchUrl.innerText, 'https://www.twitch.tv', 'Link text is reproduced as typed');
  assert.equal(twitchUrl.target, '_blank', 'Link will open in new tab/window');
});

test('game: is not detected as a URL', function(assert) {
  assert.expect(1);
  this.subject({body: "Play of the game: Bastion"});

  let urls = this.$('.js-feedlink');
  assert.equal(urls.length, 0, "game: is not detected as URL");
});

test('Strings with links and emotes are all detected', function(assert) {
  assert.expect(7);
  this.subject({
    body: 'This message contains an emote Kappa and a url https://twitch.tv/twitch and some text at the end',
    emotes: [
      {
        start: 31,
        end: 35,
        id: 25
      }
    ]
  });

  assert.equal(this.$().text().trim(), 'This message contains an emote  and a url https://twitch.tv/twitch and some text at the end');

  let urls = this.$('.js-feedlink');
  assert.equal(urls.length, 1, 'Correct number of emote elements added');

  let twitchUrl = urls[0];
  assert.equal(twitchUrl.href, 'https://twitch.tv/twitch', 'URL for link properly parsed from text');
  assert.equal(twitchUrl.innerText, 'https://twitch.tv/twitch', 'Link text is reproduced as typed');

  let emoticons = this.$('.js-emoticon');
  assert.equal(emoticons.length, 1);

  let kappa = emoticons[0];
  assert.equal(kappa.alt, 'Kappa');
  assert.equal(kappa.src, `${EMOTICONS_V1_URL}/25/1.0`);
});

test('truncateAfter param truncates text', function(assert) {
  assert.expect(1);
  this.subject({
    body: 'This message contains an emote Kappa and a url https://twitch.tv/twitch and some text at the end',
    truncateAfter: 80,
    emotes: [
      {
        start: 31,
        end: 35,
        id: 25
      }
    ]
  });

  this.$('p:last-child').remove();
  assert.equal(this.$().text().trim(), 'This message contains an emote  and a url https://twitch.tv/twitch and some');
});

test('truncateAfter param truncates links', function(assert) {
  assert.expect(2);
  this.subject({
    body: 'This message contains an emote Kappa and a url https://twitch.tv/twitch and some text at the end',
    truncateAfter: 61,
    emotes: [
      {
        start: 31,
        end: 35,
        id: 25
      }
    ]
  });

  this.$('p:last-child').remove();
  assert.equal(this.$().text().trim(), 'This message contains an emote  and a url https://twitch');
  assert.ok(this.$('a'));
});

test('truncateAfter param truncates but does not crop emotes', function(assert) {
  assert.expect(2);
  this.subject({
    body: 'This message contains an emote Kappa and a url https://twitch.tv/twitch and some text at the end',
    truncateAfter: 31,
    emotes: [
      {
        start: 31,
        end: 35,
        id: 25
      }
    ]
  });

  assert.notOk(this.$('img')[0]);

  run(() => {
    this.subject().set('truncateAfter', 32);
    this.subject()._processBody();
    let newBody = $(`<div>${this.subject().processedBody.string}</div>`);
    assert.ok(newBody.find('img')[0]);
  });
});

test('Show More link shows up when a comment is truncated', function(assert) {
  assert.expect(1);
  this.subject({
    body: 'This message contains an emote Kappa and a url https://twitch.tv/twitch and some text at the end',
    truncateAfter: 95
  });

  let showMoreLink = this.$('p:last-child');
  assert.equal(showMoreLink.text().trim(), 'Show more');
});

test('Clicking the Show More link displays the full text', function(assert) {
  assert.expect(2);
  let body = 'This message contains an emote Kappa and a url https://twitch.tv/twitch and some text at the end';
  this.subject({
    body,
    truncateAfter: 95
  });

  let processedText = $(`<div>${this.subject().processedBody.string}</div>`);
  assert.equal(processedText.text().trim().length, this.subject().truncateAfter, 'Text was correctly truncated');

  let showMoreLink = this.$('p:last-child a');
  showMoreLink.trigger('click');
  assert.equal(this.$().text().trim().length, body.length, 'Show more link displays the full text body');
});
