import moduleFor from 'web-client/tests/helpers/module-for';
import { test, skip } from 'ember-qunit';
import Service from 'ember-service';
import RSVP from 'rsvp';
import { unmarshallPinnedCheerPayload } from 'web-client/utilities/bits/parse-pinned-cheers';

moduleFor('service:bits-pinned-cheers', 'Unit | Service | bits pinned cheers', {
  beforeEach(assert) {
    this.togglePinnedCheersEnabled = (isEnabled) => {
      this.owner.lookup('service:globals').set('pCheerEnabled', isEnabled);
    };

    this.timestamp = (Date.now() * 1000000) / 1000000;

    this.payDayData = {
      recent: {
        has_recent_event: true,
        timestamp: Number(this.timestamp) * 1000000,
        tags: {
          color: "#0000FF",
          badges : [{
              badge_set_id: "bits",
              badge_set_version: 100000
            }],
          emotes : [{
              id: 88,
              start: 3,
              end: 11
            }],
            display_name: "foobar"
        },
        bits_used: 10,
        message: "VΛ PogChamp cheer10",
        username: "foo",
        channel_id: "1234",
        user_id: "12345",
        message_id: "5678",
        time_remaining_ms: 5000,
        alloted_time_ms: 5000
      },
      top: {
        has_top_event: false
      }
    };

    this.unmarshalledData = {
      recent: {
        payday_timestamp: Number(this.timestamp),
        tags: {
          badges : [{
              bits: 100000
            }],
          emotes : [{
              88: [[3, 11]]
            }],
          id: 12345,
          roomid: 1234,
          bits: 10,
          msgid: 5678
        },
        color: "#0000FF",
        amount: 10,
        message: "VΛ PogChamp cheer10",
        from: "foo",
        id: "12345",
        channel_id: "1234",
        message_id: "5678",
        duration: 5,
        totalDuration: 5,
        date: Date(this.timestamp)
      },
      top: null
    };

    this.unmarshalledData.recent.tags['display-name'] = "foobar";

    let getMostRecentPinnedCheerMock = () => {
      return new RSVP.Promise((resolve) => {
        assert.ok(true, `bits service's getMostRecentPinnedCheer was called`);
        resolve(this.payDayData);
      });
    };

    this.owner.register('service:bits', Service.extend({
      getMostRecentPinnedCheer: getMostRecentPinnedCheerMock
    }));
    this.owner.register('service:tmi', Service.extend({
      isIgnored() {
        return RSVP.resolve(false);
      }
    }));
  }
});

test('setupService - feature flag is turned off, channel is disabled', function (assert) {
  assert.expect(4);

  this.togglePinnedCheersEnabled(false);
  let service = this.subject();

  return service.setupService({
    channelId: 420,
    isChannelEnabled: false,
    channelMinimum: 5,
    channelCheerTimeout: 5
  }).catch(() => {
    assert.equal(service._channelId, 420, 'channelId');
    assert.equal(service.get('isEnabled'), false, 'pinned cheers are disabled');
    assert.equal(service.get('channelMinimum'), 5, 'channel min is correct');
    assert.equal(service.get('channelCheerTimeout'), 5, 'channel cheer timeout is correct');
  });
});

test('setupService - feature flag is turned off, channel is enabled', function (assert) {
  assert.expect(4);

  this.togglePinnedCheersEnabled(false);
  let service = this.subject();

  return service.setupService({
    channelId: 421,
    isChannelEnabled: true,
    channelMinimum: 10,
    channelCheerTimeout: 10
  }).catch(() => {
    assert.equal(service._channelId, 421, 'channelId changed');
    assert.equal(service.get('isEnabled'), false, 'pinned cheers are still disabled');
    assert.equal(service.get('channelMinimum'), 10, 'channel min changes correctly');
    assert.equal(service.get('channelCheerTimeout'), 10, 'channel cheer timeout changes correctly');
  });
});

test('setupService - feature flag is turned on, channel is disabled', function (assert) {
  assert.expect(2);

  this.togglePinnedCheersEnabled(true);
  let service = this.subject();

  return service.setupService({
    channelId: 420,
    isChannelEnabled: false
  }).catch(() => {
    assert.equal(service._channelId, 420, 'channelId');
    assert.equal(service.get('isEnabled'), false, 'pinned cheers are disabled bc channel didnt enable');
  });
});

test('setupService - feature flag is turned on, channel is enabled', function (assert) {
  assert.expect(3);

  this.togglePinnedCheersEnabled(true);
  let service = this.subject();

  return service.setupService({
    channelId: 420,
    isChannelEnabled: true
  }).then(() => {
    assert.equal(service._channelId, 420, 'channelId didnt change');
    assert.ok(service.get('isEnabled'), 'pinned cheers are enabled');
  });
});

skip('getMostRecentPinnedCheer - feature flag is turned on', function (assert) {
  assert.expect(2);

  this.togglePinnedCheersEnabled(true);
  let service = this.subject();

  return service.setupService({
    channelId: 420,
    isChannelEnabled: true
  }).then(() => {
    assert.deepEqual(service.get('recentPinnedCheer'), unmarshallPinnedCheerPayload(this.payDayData), "the payday message object comes back formatted as expected");
  });
});

test('getMostRecentPinnedCheer - feature flag is turned on and payday throws an error', function (assert) {
  assert.expect(3);

  this.togglePinnedCheersEnabled(true);
  let service = this.subject();

  let getMostRecentPinnedCheerMock = () => {
    return new RSVP.Promise(() => {
      assert.ok(true, 'bits service\'s getMostRecentPinnedCheer was called');
      throw new Error('something went wrong');
    });
  };

  this.owner.register('service:bits', Service.extend({
    getMostRecentPinnedCheer: getMostRecentPinnedCheerMock
  }));

  return service.setupService({ channelId: 420, isChannelEnabled: true }).catch(function(err) {
    assert.equal(err.message, "something went wrong", "an error is thrown");
    assert.equal(service.get('recentPinnedCheer'), null, "without pinned cheers enabled, we receive nothing");
  });
});

test('getMostRecentPinnedCheer - feature flag is turned off', function (assert) {
  assert.expect(2);

  this.togglePinnedCheersEnabled(false);
  let service = this.subject();

  service.setupService({
    channelId: 420,
    isChannelEnabled: false
  });

  return service._getMostRecentPinnedCheer().catch(function(err) {
    assert.equal(err, undefined, "no error is thrown");
    assert.equal(service.get('currentPinnedCheer'), null, "without pinned cheers enabled, we receive nothing");
  });
});

test('getMostRecentPinnedCheer - user is ignored', function (assert) {
  assert.expect(2);

  this.owner.register('service:tmi', Service.extend({
    isIgnored() {
      return RSVP.resolve(true);
    }
  }));
  this.togglePinnedCheersEnabled(true);

  let service = this.subject();

  return service.setupService({
    channelId: 420,
    isChannelEnabled: true
  }).then(() => {
    assert.equal(service.get('currentPinnedCheer'), null, 'user is ignored, no pinned cheer');
  });
});

test('reset', function (assert) {
  assert.expect(5);

  this.togglePinnedCheersEnabled(true);
  let service = this.subject();

  return service.setupService({
    channelId: 420,
    isChannelEnabled: true,
    channelMinimum: 5,
    channelCheerTimeout: 5
  }).then(() => {
    service.reset();

    assert.equal(service._channelId, '', 'channelId is blank');
    assert.equal(service.get('isEnabled'), false, 'pinned cheers are disabled');
    assert.equal(service.get('channelMinimum'), 0, 'channel min is 0');
    assert.equal(service.get('channelCheerTimeout'), 0, 'cheer timeout is 0');
  });
});
