import { moduleForComponent, test } from 'ember-qunit';
import { helper } from 'ember-helper';
import RSVP from 'rsvp';

import { EMOTICONS_V1_URL } from 'web-client/utilities/urls/static-cdn';
import { SHARE_MESSAGE_CHARACTER_LIMIT } from 'web-client/components/chat/resub-notification/component';

const CHANNEL_NAME = 'Twitch';
const RESUB_NOTIFICATION = { token_id: 9000, token_month: 12 }; // eslint-disable-line camelcase
const SHARE_MESSAGE = 'custom message!';

let resubNotification;

moduleForComponent('chat/resub-notification', 'Unit | Component | resub notification', {
  unit: true,

  setup() {
    this.register('helper:i18n', helper(([value]) => value));
  }
});

test('resubNotice computed property', function (assert) {
  assert.expect(1);

  resubNotification = this.subject({ resubNotification: RESUB_NOTIFICATION });

  assert.equal(
    resubNotification.get('resubNotice'),
    `It's your ${ RESUB_NOTIFICATION.token_month } month anniversary!`,
    'RESUB_NOTICE_TEMPLATE is replaced with month'
  );
});

test('detailedResubNotice computed property', function (assert) {
  assert.expect(1);

  resubNotification = this.subject({
    channelName: CHANNEL_NAME,
    resubNotification: RESUB_NOTIFICATION
  });

  assert.equal(
    resubNotification.get('detailedResubNotice'),
    `Hooray! Let <span class="strong">${ CHANNEL_NAME }</span> know it's your ${ RESUB_NOTIFICATION.token_month } month anniversary.`,
    'DETAILED_RESUB_NOTICE_TEMPLATE is replaced with bolded channel name and non-bolded month'
  );
});

test('it generates a valid URL to an emoticon', function (assert) {
  assert.expect(1);

  resubNotification = this.subject({ _randomizeEmoticonId() { return 9000; } });

  assert.equal(
    resubNotification.get('randomEmoticonUrl'),
    `${ EMOTICONS_V1_URL }/9000/2.0`,
    'randomEmoticonUrl computed property is valid'
  );
});

test('it sets an ultra rare emoticon neck animation (at 1/100 chance)', function (assert) {
  assert.expect(1);

  resubNotification = this.subject({ _randomizeUltraRareEmoticonNeckAnimation() { return 99; } });

  assert.ok(
    resubNotification.get('isUltraRareEmoticonNeckAnimation'),
    'isUltraRareEmoticonNeckAnimation computed property is valid'
  );
});

test('it does not set an ultra rare emoticon neck animation (at 99/100 chance)', function (assert) {
  assert.expect(1);

  resubNotification = this.subject({ _randomizeUltraRareEmoticonNeckAnimation() { return 100; } });

  assert.notOk(
    resubNotification.get('isUltraRareEmoticonNeckAnimation'),
    'isUltraRareEmoticonNeckAnimation computed property is valid'
  );
});

test(`it calculates characters under ${ SHARE_MESSAGE_CHARACTER_LIMIT } limit for share message`, function (assert) {
  assert.expect(1);

  resubNotification = this.subject({ message: SHARE_MESSAGE });

  assert.notOk(resubNotification.get('isOverCharacterLimit'), 'isOverCharacterLimit computed property is valid');
});

test(`it calculates characters at ${ SHARE_MESSAGE_CHARACTER_LIMIT } limit for share message`, function (assert) {
  assert.expect(1);

  let atLimitMessage = new Array(SHARE_MESSAGE_CHARACTER_LIMIT).join('z');

  resubNotification = this.subject({ message: atLimitMessage });

  assert.notOk(resubNotification.get('isOverCharacterLimit'), 'isOverCharacterLimit computed property is valid');
});

test(`it calculates characters over ${ SHARE_MESSAGE_CHARACTER_LIMIT } limit for share message`, function (assert) {
  assert.expect(2);

  let overLimitMessage = new Array(101).join(SHARE_MESSAGE);

  resubNotification = this.subject({ message: overLimitMessage });

  assert.ok(resubNotification.get('isOverCharacterLimit'), 'isOverCharacterLimit computed property is valid');
  assert.equal(
    resubNotification.get('overCharacterLimitButtonText'),
    SHARE_MESSAGE_CHARACTER_LIMIT - overLimitMessage.length,
    'overCharacterLimitButtonText computed property is valid'
  );
});

test('setIsShowingBalloon action', function (assert) {
  assert.expect(2);

  resubNotification = this.subject();

  assert.notOk(resubNotification.get('isShowingBalloon'), 'isShowingBalloon defaults to false');

  resubNotification.send('setIsShowingBalloon', true);

  assert.ok(resubNotification.get('isShowingBalloon'), 'isShowingBalloon is set to true');
});

test('shareMessage action', function (assert) {
  assert.expect(6);

  let done = assert.async(1);

  function closeResubNotification () {
    assert.ok(true, 'passed in closeResubNotification action is invoked');
  }

  function postResubMessage (resubTokenId, message) {
    assert.equal(resubTokenId, RESUB_NOTIFICATION.token_id, 'resub token ID is passed');
    assert.equal(message, SHARE_MESSAGE, 'resub share message is passed');

    return new RSVP.resolve();
  }

  resubNotification = this.subject({
    resubNotification: RESUB_NOTIFICATION,
    message: SHARE_MESSAGE,
    closeResubNotification: closeResubNotification,
    postResubMessage: postResubMessage
  });

  assert.notOk(resubNotification.get('isSharingMessage'), 'isSharingMessage CP defaults to false');

  let shareMessageAction = resubNotification.actions.shareMessage;
  let resubTokenId = resubNotification.get('resubNotification.token_id');
  let message = resubNotification.get('message');

  shareMessageAction.call(resubNotification, resubTokenId, message).finally(() => {
    assert.notOk(resubNotification.get('isSharingMessage'), 'isSharingMessage CP is set to false');

    done();
  });

  assert.ok(resubNotification.get('isSharingMessage'), 'isSharingMessage CP is set to true');
});
