import { moduleForComponent, test } from 'ember-qunit';
import { assign } from 'ember-platform';
import run from 'ember-runloop';
import { helper } from 'ember-helper';

let defaultChannelProduct = {
  'name': 'ash',
  'product_url': 'http://www.buymysubscriptionhere.com',
  'price': '50 Pokedollars',
  'emoticons': [
    {
      'id': 1,
      'width': 28,
      'height': 28,
      "state":"active",
      "regex":"pokeBall",
      "emoticon_set":155,
      "url":"http://twitchtvemotes.twitch.tv/pokeball.png",
      "subscriber_only":true
    }
  ]
};

let defaultAllEmotes = {
  emoticon_sets: {
    "0": [
      { id: 25, code: "Kappa" },
      { id: 41, code: "Kreygasm" }
    ],
    "457":[
      {  "id":2867, "code":"KappaHD" },
      {  "id":23195, "code":"duDudu" },
      {  "id":23541, "code":"PraiseIt" }
    ],
    "155":[
      {  "id":4216, "code":"cerFlan" },
      {  "id":12518, "code":"cerKupo" },
      {  "id":13930, "code":"cerFancy" },
      {  "id":15517, "code":"cerHype" },
      {  "id":29881, "code":"cerRIP" }
    ]
  }
};

moduleForComponent('emoticon-selector', 'Emoticon Selector Component', {
  needs: ['component:tipsy-wrapper'],
  setup() {
    this.register('helper:i18n', helper(([value]) => value));
    this.getComponent = function (args) {
      let defaults = {
        channelProduct: defaultChannelProduct,
        allEmotes: defaultAllEmotes
      };
      return this.subject(assign(defaults, args));
    };
  }
});

test('it works!', function (assert) {
  assert.ok(this.getComponent());
});

test('if isSubscribed is false, then the channel emoticons have the locked class', function (assert) {
  this.getComponent({isSubscribed: false});
  assert.equal(this.$().find('.channel-emotes .emoticon').hasClass('locked'), true);
});

test('if subscribed, then the channel emoticons do not have the locked class', function (assert) {
  this.getComponent({isSubscribed: true});
  assert.equal(this.$().find('.channel-emotes .emoticon').hasClass('locked'), false);
});

test('can set price on subscribe button', function (assert) {
  let args = defaultChannelProduct;
  args.price = '60 Pokedollars!';
  this.getComponent(args);
  assert.equal(this.$().find('.subscribe-price').text(), '60 Pokedollars!');
});

test('can set url on subscribe button', function (assert) {
  this.getComponent();
  assert.equal(this.$().find('.subscribe-button').attr('href'), 'http://www.buymysubscriptionhere.com?ref=emoticon-selector-subscribe-button');
});

test('can set subscribe unlock text', function (assert) {
  this.getComponent({subscribeToUnlockText: 'Click here lol'});
  assert.equal(this.$().find('#non-subscriber-message .unlock-text').text(), 'Click here lol');
});

test('can set subscribe button text', function (assert) {
  this.getComponent({subscribeText: 'Subscribe now!'});
  assert.equal(this.$().find('.subscribe-text').text(), 'Subscribe now!');
});

test('can hide tabs', function (assert) {
  this.getComponent({enableTabs: false});
  assert.equal(this.$().find('.js-es__tabs').hasClass('hidden'), true);
});

test('channel emoticon click sends default action if subscribed', function (assert) {
  assert.expect(1);
  let targetObj = {
    actionFunc() {
      assert.ok(true, 'selectEmoticon action was called');
    }
  };
  let component = this.getComponent({isSubscribed: true});
  component.set('action', 'actionFunc');
  component.set('targetObject', targetObj);
  this.$().find('.channel-emotes .emoticon').click();
});

test('channel emoticon click does not send default action if not subscribed', function (assert) {
  assert.expect(0);
  let targetObj = {
    actionFunc() {
      assert.ok(true, 'selectEmoticon action was called');
    }
  };

  let component = this.getComponent({isSubscribed: false});
  component.set('action', 'actionFunc');
  component.set('targetObject', targetObj);
  this.$().find('.channel-emotes .emoticon').click();
});

test('clicking on all tab shows all emotes', function (assert) {
  this.getComponent();
  assert.equal(this.$().find('.js-es__tab.all').hasClass('active'), false);
  this.$().find('.js-es__tabs .js-es__tab.all').click();
  assert.equal(this.$().find('.js-es__tab.all').hasClass('active'), true);
});

test('clicking on channel tab shows channel emotes', function (assert) {
  let component = this.getComponent();
  component.set('showChannelEmotes', false);
  assert.equal(this.$().find('.js-es__tab.channel').hasClass('active'), false);
  this.$().find('.js-es__tabs .js-es__tab.channel').click();
  assert.equal(this.$().find('.js-es__tab.channel').hasClass('active'), true);
});

test('all emoticon click sends default action if subscribed', function (assert) {
  assert.expect(1);
  let component = this.getComponent({isSubscribed: true});
  let targetObj = {
    actionFunc() {
      assert.ok(true, 'selectEmoticon action was called');
    }
  };
  component.set('action', 'actionFunc');
  component.set('targetObject', targetObj);
  this.$().find('.all-emotes .emoticon')[0].click();
});

test('all emoticon click sends default action if not subscribed', function (assert) {
  assert.expect(1);
  let component = this.getComponent({isSubscribed: false});
  let targetObj = {
    actionFunc() {
      assert.ok(true, 'selectEmoticon action was called');
    }
  };
  component.set('action', 'actionFunc');
  component.set('targetObject', targetObj);
  this.$().find('.all-emotes .emoticon')[0].click();
});

test('emote sets in monkey turbo emoticons are listed at the bottom', function (assert) {
  let allEmotes = {
    emoticon_sets: {
      '1': [{id: 1, code: 'emote1'}],
      '42': [{id: 2, code: 'monkeyemote1'}]
    }
  };
  this.getComponent({allEmotes: allEmotes});
  assert.equal(this.$('.all-emotes .emoticon-grid .emoticon:eq(0)').attr('original-title'), 'emote1');
  assert.equal(this.$('.all-emotes .emoticon-grid .emoticon:eq(1)').attr('original-title'), 'monkeyemote1');
});

test('emote sets in global emote list are listed at the bottom', function (assert) {
  let allEmotes = {
    emoticon_sets: {
      '1': [{id: 1, code: 'emote1'}],
      '0': [{id: 2, code: 'globalemote'}]
    }
  };
  this.getComponent({allEmotes: allEmotes});
  assert.equal(this.$('.all-emotes .emoticon-grid .emoticon:eq(0)').attr('original-title'), 'emote1');
  assert.equal(this.$('.all-emotes .emoticon-grid .emoticon:eq(1)').attr('original-title'), 'globalemote');
});

test('emote sets in robot turbo emoticons are listed at the bottom', function (assert) {
  let allEmotes = {
    emoticon_sets: {
      '1': [{id: 1, code: 'emote1'}],
      '33': [{id: 2, code: 'robotemote1'}]
    }
  };
  this.getComponent({allEmotes: allEmotes});
  assert.equal(this.$('.all-emotes .emoticon-grid .emoticon:eq(0)').attr('original-title'), 'emote1');
  assert.equal(this.$('.all-emotes .emoticon-grid .emoticon:eq(1)').attr('original-title'), 'robotemote1');
});

test('emote set of turbo emotes are listed at the bottom', function (assert) {
  let allEmotes = {
    emoticon_sets: {
      '1': [{id: 1, code: 'emote1'}],
      '457': [{id: 2, code: 'KappaHD'}]
    }
  };
  this.getComponent({allEmotes: allEmotes});
  assert.equal(this.$('.all-emotes .emoticon-grid .emoticon:eq(0)').attr('original-title'), 'emote1');
  assert.equal(this.$('.all-emotes .emoticon-grid .emoticon:eq(1)').attr('original-title'), 'KappaHD');
});

test('emoticons with regexes in REGEX_EMOTE_MAP have their display name changed', function (assert) {
  let allEmotes = {
    emoticon_sets: {
      '0': [{id: 25, code: 'Kappa'}]
    }
  };
  let component = this.getComponent({allEmotes: allEmotes});
  component.set('REGEX_EMOTE_MAP', { 'Kappa': 'GoldenKappa' });
  assert.equal(this.$('.all-emotes .emoticon-grid .emoticon:eq(0)').attr('original-title'), 'GoldenKappa');
});

test('only active channel emotes are displayed in the selector', function (assert) {
  let channelProduct = defaultChannelProduct;
  channelProduct.emoticons = [
    { id: 1,
      state: 'inactive',
      regex: 'mew',
      emoticon_set: 151,
      url: 'emotesurl',
      subscriber_only: true
    },
    { id: 1,
      state: 'active',
      regex: 'mewtwo',
      emoticon_set: 151,
      url: 'emotesurl',
      subscriber_only: true
    }
  ];

  this.getComponent({channelProduct: channelProduct});
  assert.equal(this.$().find('.channel-emotes .emoticon').length, 1);
  assert.equal(this.$('.channel-emotes .emoticon:eq(0)').attr('original-title'), 'mewtwo');
});

test('if all emotes is empty, then the all emotes tab is hidden', function (assert) {
  let allEmotes = {};
  this.getComponent({allEmotes: allEmotes});
  assert.equal(this.$().find('.js-es__tabs .js-es__tab.all').hasClass('hidden'), true);
});

test('if no channel emotes then all emotes are shown', function (assert) {
  let channelProduct = {};
  let component = this.getComponent({channelProduct: channelProduct});
  assert.equal(this.$().find('.js-es__tabs .js-es__tab.all').hasClass('hidden'), false);
  assert.equal(component.get('showChannelEmotes'), false);
});

test('if no channel emotes then channel tab is hidden', function (assert) {
  let channelProduct = {};
  this.getComponent({channelProduct: channelProduct});
  assert.equal(this.$().find('.js-es__tabs .js-es__tab.channel').hasClass('hidden'), true);
});

test('if no all emotes then all emotes tab is hidden', function (assert) {
  let allEmotes = {};
  this.getComponent({allEmotes: allEmotes});
  assert.equal(this.$().find('.js-es__tabs .js-es__tab.all').hasClass('hidden'), true);
});

test('emoticon selector sorts by emote id', function (assert) {
  let allEmotes = {
    emoticon_sets: {
      '0': [
        { id: 41, code: 'Kreygasm' },
        { id: 25, code: 'Kappa' }
      ]
    }
  };
  this.getComponent({allEmotes: allEmotes});

  assert.equal(this.$('.all-emotes .emoticon:eq(0)').attr('original-title'), 'Kappa');
  assert.equal(this.$('.all-emotes .emoticon:eq(1)').attr('original-title'), 'Kreygasm');
});

test('emote sets without emotes are hidden', function (assert) {
  assert.expect(2);
  let component = this.getComponent();
  assert.ok(this.$().find('.emote-set').length);
  run(() => {
    component.set('filter', "string that doesn't match any emotes");
    run.next(() => {
      assert.equal(this.$().find('.emote-set').length, 0);
    });
  });
});
