import moduleForComponent from 'web-client/tests/helpers/module-for-component';
import { test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import wait from 'ember-test-helpers/wait';
import Service from 'ember-service';
import AutohostUI from 'web-client/tests/pages/autohost-settings';
import RSVP from 'rsvp';

const includes = (haystack, needle) => haystack.indexOf(needle) !== -1;
const fakeSearch = Service.extend({
  init() {
    this._super(...arguments);
    this.users = [];
  },

  queryForType(type, term) {
    let hits = this.users.filter((m) => includes(m.name || m.title, term));
    let results = {
      index: type,
      hits,
      nbHits: hits.length,
      hitsPerPage: 1
    };

    return RSVP.Promise.resolve({users: results});
  }
});

moduleForComponent('autohost-search', {
  beforeEach() {
    this.ui = new AutohostUI(this);
    this.owner.register('service:search', fakeSearch);
    this.inject.service('search');
  },

  afterEach() {
    this.get('search').setProperties({});
  }
});

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

  this.render(hbs`{{autohost-search}}`);

  return wait().then(() => {
    assert.equal(this.ui.searchInput().length, 1, 'search appears');
    assert.equal(this.ui.searchResultPanel().length, 1, 'search panel results appear');
    return wait();
  });
});

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

  this.render(hbs`{{autohost-search}}`);

  return wait().then(() => {
    this.ui.enterTerm('lsdkjflkdjskf');
    return wait();
  }).then(() => {
    assert.equal(this.ui.searchHits().length, 0, 'no results');
    return wait();
  });
});

test('search with results', function(assert) {
  assert.expect(4);

  this.get('search').setProperties({
    users: [
      { login: 'prefix-twitch', name: 'prefix-twitch' },
      { login: 'twitch', name: 'twitch' }
    ]
  });

  let addedChannels = [];
  let removedChannels = [];
  let sources = [];
  this.set('addAction', function (channel, source) {
    addedChannels.push(channel);
    sources.push(source);
  });
  this.set('undoAction', function (channel) {
    removedChannels.push(channel);
  });
  this.render(hbs`{{autohost-search clickAction=(action addAction) undoAction=(action undoAction)}}`);

  return wait().then(() => {
    this.ui.enterTerm('prefix');
    return wait();
  }).then(() => {
    assert.equal(this.ui.searchHits().length, 1, 'channel that matches the term is in results');
    this.ui.searchResultsAddButtons()[0].click();
    return wait();
  }).then(() => {
    assert.equal(addedChannels.length, 1, 'added channel');
    assert.equal(addedChannels[0].name, 'prefix-twitch', 'correct channel added');
    assert.equal(sources[0], 'search', 'correct source');
    return wait();
  });
});

test('no header for no recommended results', function(assert) {
  assert.expect(1);

  this.set('recommendedResults', []);
  this.render(hbs`{{autohost-search recommendedResults=recommendedResults}}`);

  return wait().then(() => {
    assert.equal(this.ui.recommendedResultsHeader().length, 0, 'recommended results section not there');
    return wait();
  });
});

test('shows recommended results', function(assert) {
  assert.expect(2);

  this.set('addAction', () => {});
  this.set('recommendedResults', [{channel: {login: 'twitch', display_name: 'Twitch'}}]);
  this.render(hbs`{{autohost-search clickAction=(action addAction) undoAction=(action addAction) recommendedResults=recommendedResults}}`);

  return wait().then(() => {
    assert.equal(this.ui.recommendedResultsHeader().length, 1, 'recommended results section appears');
    assert.equal(this.ui.recommendedResults().length, 1, 'recommended results appear');
    return wait();
  });
});

test('disable channels in the map', function(assert) {
  assert.expect(2);

  this.get('search').setProperties({
    users: [
      { login: 'prefix-twitch', name: 'prefix-twitch' }
    ]
  });

  this.set('addAction', () => {});
  this.set('channelsMap', {'prefix-twitch': true});
  this.render(hbs`{{autohost-search clickAction=(action addAction) undoAction=(action addAction) channelsMap=channelsMap}}`);

  return wait().then(() => {
    this.ui.enterTerm('prefix');
    return wait();
  }).then(() => {
    assert.equal(this.ui.searchHits().length, 1, 'channel that matches the term is in results');
    assert.equal(this.ui.searchResultsRemoveButtons().length, 1, 'channel button is remove');
    return wait();
  });
});

test('deleting term clears results', function(assert) {
  assert.expect(2);

  this.get('search').setProperties({
    users: [
      { login: 'prefix-twitch', name: 'prefix-twitch' }
    ]
  });

  this.set('addAction', () => {});
  this.render(hbs`{{autohost-search clickAction=(action addAction) undoAction=(action addAction)}}`);

  return wait().then(() => {
    this.ui.enterTerm('prefix');
    return wait();
  }).then(() => {
    assert.equal(this.ui.searchHits().length, 1, 'channel that matches the term is in results');
    this.ui.enterTerm('');
    return wait();
  }).then(() => {
    assert.equal(this.ui.searchHits().length, 0, 'results are cleared');
    return wait();
  });
});
