import moduleForComponent from 'web-client/tests/helpers/module-for-component';
import { test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import Service from 'ember-service';
import RSVP from 'rsvp';
import { LOCALSTORAGE_KEYS as BITS_STORAGE_KEYS } from 'web-client/utilities/bits/constants-config';
import { AuthenticatedSession } from 'web-client/tests/helpers/mock-session-service';
import wait from 'ember-test-helpers/wait';

let mockRoomSvc = Service.extend({
  isOwnChannel: false
});
let mockStringsSvc = Service.extend({
  isLoaded: false
});
let mockPinnedCheersSvc = Service.extend({
  recentPinnedCheer: null,
  topPinnedCheer: null,

  getMostRecentPinnedCheer() {
    return RSVP.resolve();
  },
  canDismissPinnedCheer() {
    return true;
  }
});
let mockStorageSvc = Service.extend({
  keys: {},

  unknownProperty(key) {
    return this.get(`keys.${key}`);
  },

  setUnknownProperty(key, value) {
    this.propertyWillChange(key);
    this.set(`keys.${key}`, value);
    this.propertyDidChange(key);

    return this.get(`keys.${key}`);
  }
});
let mockEmotesSvc = Service.extend({
  getMessagePrefix() {
    return 'Kappa';
  }
});

moduleForComponent('bits/pinned-cheers/anchor', 'Integration | Component | bits/pinned cheers/anchor', {
  beforeEach() {
    this.owner.register('service:bits-room', mockRoomSvc);
    this.owner.register('service:bits-strings', mockStringsSvc);
    this.owner.register('service:bits-pinned-cheers', mockPinnedCheersSvc);
    this.owner.register('service:bits-emotes', mockEmotesSvc);
    this.owner.register('service:storage', mockStorageSvc);
    this.owner.register('service:session', AuthenticatedSession);

    this.setIsOwnChannel = (isOwnChannel) => {
      this.owner.lookup('service:bits-room').set('isOwnChannel', isOwnChannel);
    };
    this.setStringsIsLoaded = (isLoaded) => {
      this.owner.lookup('service:bits-strings').set('isLoaded', isLoaded);
    };
    this.setHasPinnedCheer = (hasRecentPinnedCheer) => {
      let svc = this.owner.lookup('service:bits-pinned-cheers');

      if (hasRecentPinnedCheer) {
        svc.set('recentPinnedCheer', { message: 'recent cheer' });
        svc.set('showRecentCheerA', true);
        svc.set('recentPinnedCheerA', [{ message: 'recent cheer' }]);
      } else {
        svc.set('recentPinnedCheer', null);
        svc.set('showRecentCheerA', false);
        svc.set('recentPinnedCheerA', []);
      }
    };
    this.setHasTopPinnedCheer = (hasTopPinnedCheer) => {
      let svc = this.owner.lookup('service:bits-pinned-cheers');

      if (hasTopPinnedCheer) {
        svc.set('topPinnedCheer', { message: 'top cheer' });
        svc.set('showTopCheerA', true);
        svc.set('topPinnedCheerA', [{ message: 'top cheer' }]);
      } else {
        svc.set('topPinnedCheer', null);
        svc.set('showTopCheerA', false);
        svc.set('topPinnedCheerA', []);
      }
    };
    this.setBroadcasterIntroDismissed = (isDismissed) => {
      this.owner.lookup('service:storage').set(BITS_STORAGE_KEYS.SEEN_PCHEER_BROADCASTER_NOTIFICATION, isDismissed);
    };
    this.setViewerIntroDismissed = (isDismissed) => {
      this.owner.lookup('service:storage').set(BITS_STORAGE_KEYS.SEEN_PCHEER_VIEWER_NOTIFICATION, isDismissed);
    };

    this.owner.lookup('service:bits-pinned-cheers').set('topPinnedCheer', null);

    this.on('adjustContainer', () => {});
    this.defaultTemplate = hbs`{{bits/pinned-cheers/anchor adjustContainer=(action 'adjustContainer')}}`;
  },

  afterEach() {
    this.setBroadcasterIntroDismissed(false);
    this.setViewerIntroDismissed(false);
  }
});

test('not visible - strings loaded/not loaded', function (assert) {
  // by setting this to true, it verifies that the isVisible check short circuits at checking strings/rendering config
  this.setHasPinnedCheer(true);
  this.setStringsIsLoaded(false);

  this.render(this.defaultTemplate);

  return wait().then(() => {
    assert.elementCount('.hidden', 1, 'Not visible when strings not loaded');
  });
});

test('not visible - no recent cheer and has dismissed every intro', function (assert) {
  this.setStringsIsLoaded(true);
  this.setHasPinnedCheer(false);
  this.setBroadcasterIntroDismissed(true);
  this.setViewerIntroDismissed(true);

  this.render(hbs`{{bits/pinned-cheers/anchor}}`);

  return wait().then(() => {
    assert.elementCount('.hidden', 1, `Not visible there's nothing to show`);
  });
});

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

  this.setStringsIsLoaded(true);
  this.setHasPinnedCheer(true);

  this.render(this.defaultTemplate);

  return wait().then(() => {
    assert.elementCount('.js-bits-pinned-cheers-recent-cheer', 2, 'Recent cheer rendered');
  });
});

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

  this.setStringsIsLoaded(true);
  this.setHasPinnedCheer(false);
  this.setIsOwnChannel(true);
  this.setBroadcasterIntroDismissed(false);
  this.setViewerIntroDismissed(true);

  this.render(hbs`{{bits/pinned-cheers/anchor}}`);

  return wait().then(() => {
    assert.elementCount('.js-bits-pinned-cheers-intro-broadcaster', 1, 'Broadcaster intro rendered');
  });
});

test('viewer intro', function (assert) {
  this.setStringsIsLoaded(true);
  this.setHasPinnedCheer(false);
  this.setBroadcasterIntroDismissed(true);
  this.setViewerIntroDismissed(false);

  this.render(hbs`{{bits/pinned-cheers/anchor}}`);

  return wait().then(() => {
    assert.elementCount('.js-bits-pinned-cheers-intro-viewer', 1, 'viewer intro rendered');
  });
});

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

  this.setHasTopPinnedCheer(false);
  this.setHasPinnedCheer(false);

  this.set('adjustContainerValue', null);
  this.on('adjustContainer', (value) => {
    this.set('adjustContainerValue', value);
  });

  this.render(this.defaultTemplate);

  return wait().then(() => {
    assert.equal(this.get('adjustContainerValue'), null, 'adjustContainer not invoked');

    this.setHasPinnedCheer(true);
    return wait();
  }).then(() => {
    assert.equal(this.get('adjustContainerValue'), 76, 'recent cheer');

    this.setHasPinnedCheer(false);
    this.setHasTopPinnedCheer(true);
    return wait();
  }).then(() => {
    assert.equal(this.get('adjustContainerValue'), 30, 'top cheer');

    this.setHasPinnedCheer(false);
    this.setHasTopPinnedCheer(false);
    return wait();
  }).then(() => {
    assert.equal(this.get('adjustContainerValue'), 0, 'pinned cheers removed');
  });
});
