import { moduleFor, test } from 'ember-qunit';
import RSVP from 'rsvp';
import Service from 'ember-service';
import wait from 'ember-test-helpers/wait';
import { CHEER_PREFIX } from 'web-client/utilities/bits/constants-config';

const CONFIG = {
  actions: [
    {
      'prefix': 'PogChamp',
      'scales': [1, 2],
      'backgrounds': ['light'],
      'states': ['animated'],
      'tiers': [
        {
          'min_bits': 1,
          'id': '1',
          'color': 'pogchamp1',
          'images': {
            'light': {
              'animated': {
                '1': 'pogchamp1.gif',
                '2': 'pogchamp1.2x.gif'
              }
            }
          }
        }, {
          'min_bits': 100,
          'id': '100',
          'color': 'pogchamp100',
          'images': {
            'light': {
              'animated': {
                '1': 'pogchamp100.gif',
                '2': 'pogchamp100.2x.gif'
              }
            }
          }
        }
      ]
    }, {
      'prefix': 'BibleThump',
      'scales': [1, 2],
      'backgrounds': ['light'],
      'states': ['animated'],
      'tiers': [
        {
          'min_bits': 1,
          'id': '1',
          'color': 'biblethump1',
          'images': {
            'light': {
              'animated': {
                '1': 'biblethump1.gif',
                '2': 'biblethump1.2x.gif'
              }
            }
          }
        }, {
          'min_bits': 100,
          'id': '100',
          'color': 'biblethump100',
          'images': {
            'light': {
              'animated': {
                '1': 'biblethump100.gif',
                '2': 'biblethump100.2x.gif'
              }
            }
          }
        }
      ]
    }
  ]
};

moduleFor('service:bits-emotes', 'Unit | Service | bits emotes', {
  needs: [
    'service:layout',
    'service:chat-settings'
  ],
  beforeEach() {
    this.register('service:bits', Service.extend({
      getActions() {
        return RSVP.resolve(CONFIG);
      }
    }));
  }
});

test('init and caching', function (assert) {
  assert.expect(6);

  this.container.lookup('service:bits').set('getActions', () => {
    assert.ok(true, 'getActions is called');

    return RSVP.resolve(CONFIG);
  });

  let service = this.subject();

  return wait().then(() => {
    assert.ok(service.get('isLoaded'), 'config has been loaded');

    assert.ok(service.get('prefixes'), 'prefixes set');
    assert.ok(service.get('regexes'), 'regexes set');
    assert.ok(service.get('emoteConfig'), 'emoteConfig set');
    assert.ok(service.get('emoteImageMap'), 'emoteImageMap set');

    // re-initializing won't call bits.getActions again
    service.init();
  });
});

test('getImageSrc', function (assert) {
  assert.expect(1);

  let service = this.subject();

  return wait().then(() => {
    assert.equal(service.getImageSrc(100, 'pogchamp', false, false, 2), 'pogchamp100.2x.gif');
  });
});

test('getImageSrcSet', function (assert) {
  assert.expect(1);

  let service = this.subject();

  return wait().then(() => {
    assert.equal(service.getImageSrcSet(100, 'pogchamp', false, false, 1),
      'pogchamp100.gif 1x, pogchamp100.2x.gif 2x');
  });
});

test('getTierColor', function (assert) {
  assert.expect(1);

  let service = this.subject();

  return wait().then(() => {
    assert.equal(service.getTierColor(100, 'pogchamp'), 'pogchamp100');
  });
});

test('getTiers', function (assert) {
  assert.expect(1);

  let service = this.subject();

  return wait().then(() => {
    assert.deepEqual(service.getTiers('pogchamp'), [1, 100]);
  });
});

test('getPrefixData', function (assert) {
  assert.expect(1);

  let service = this.subject();

  return wait().then(() => {
    assert.deepEqual(service.getPrefixData('pogchamp'), CONFIG.actions[0]);
  });
});

test('getMessagePrefix', function (assert) {
  assert.expect(3);

  let service = this.subject();

  return wait().then(() => {
    assert.equal(service.getMessagePrefix('pogchamp1 pogchamp1 kappa'), 'PogChamp', 'only 1 prefix');
    assert.equal(service.getMessagePrefix('pogchamp1 biblethump1'), CHEER_PREFIX, 'mixed prefixes');
    assert.equal(service.getMessagePrefix('pogchamp pogchamp'), CHEER_PREFIX, 'no valid prefixes');
  });
});

test('invalid prefix when calling public functions', function (assert) {
  assert.expect(6);

  let service = this.subject();

  return wait().then(() => {
    assert.equal(service.getImageSrc(100, 'gachi'), null);
    assert.equal(service.getImageSrcSet(100, 'gachi'), null);
    assert.equal(service.getTierColor(100, 'gachi'), null);
    assert.deepEqual(service.getTiers('gachi'), []);
    assert.equal(service.getPrefixData('gachi'), null);
    assert.equal(service.getMessagePrefix(''), CHEER_PREFIX);
  });
});

test('not loaded when calling public functions', function (assert) {
  assert.expect(6);

  this.container.lookup('service:bits').set('getActions', () => {
    return RSVP.reject();
  });

  let service = this.subject();

  return wait().then(() => {
    assert.equal(service.getImageSrc(100, 'gachi'), null);
    assert.equal(service.getImageSrcSet(100, 'gachi'), null);
    assert.equal(service.getTierColor(100, 'gachi'), null);
    assert.deepEqual(service.getTiers('gachi'), []);
    assert.equal(service.getPrefixData('gachi'), null);
    assert.equal(service.getMessagePrefix('pogchamp100'), CHEER_PREFIX);
  });
});

test('_parseActionsPayload', function (assert) {
  assert.expect(4);

  let service = this.subject();

  return wait().then(() => {
    let {
      prefixes,
      regexes,
      emoteConfig,
      emoteImageMap
    } = service._parseActionsPayload(CONFIG);

    assert.deepEqual(prefixes, ['PogChamp', 'BibleThump'], 'prefixes correct');

    assert.deepEqual(regexes, [
      {
        prefix: 'PogChamp',
        valid: /^\s*PogChamp\d+\s*$/i,
        zeroValue: /^\s*PogChamp0+\s*$/i
      }, {
        prefix: 'BibleThump',
        valid: /^\s*BibleThump\d+\s*$/i,
        zeroValue: /^\s*BibleThump0+\s*$/i
      }
    ], 'regexes correct');

    assert.deepEqual(emoteConfig, {
      'pogchamp': CONFIG.actions[0],
      'biblethump': CONFIG.actions[1]
    }, 'emoteConfig correct');

    assert.deepEqual(emoteImageMap, {
      'pogchamp': {
        '1': {
          'light': {
            'animated': {
              '1': 'pogchamp1.gif',
              '2': 'pogchamp1.2x.gif'
            }
          }
        },
        '100': {
          'light': {
            'animated': {
              '1': 'pogchamp100.gif',
              '2': 'pogchamp100.2x.gif'
            }
          }
        }
      },
      'biblethump': {
        '1': {
          'light': {
            'animated': {
              '1': 'biblethump1.gif',
              '2': 'biblethump1.2x.gif'
            }
          }
        },
        '100': {
          'light': {
            'animated': {
              '1': 'biblethump100.gif',
              '2': 'biblethump100.2x.gif'
            }
          }
        }
      }
    }, 'emoteImageMap correct');
  });
});
