import Component from 'ember-component';
import injectService from 'ember-service/inject';
import computed from 'ember-computed';
import { assign } from 'ember-platform';
import RSVP from 'rsvp';
import { assert } from 'ember-metal/utils';
import { VIDEO_TYPE } from 'web-client/services/search';
import { keyboardListener } from 'web-client/utilities/keyboard';

const SCROLL_BUFFER = 500;
const HITS_PER_PAGE = 5;
const EMPTY_TERM_OPTIONS = {
  indexName: 'vod_by_created_at',
  hitsPerPage: HITS_PER_PAGE
};

const TERM_OPTIONS = {
  hitsPerPage: HITS_PER_PAGE
};

export default Component.extend({
  search: injectService(),
  ownerLogin: '',

  init() {
    this._super(...arguments);

    if (this.get('ownerLogin') === '') {
      assert("The 'ownerLogin' prop is required for this component.");
    }

    this.set('scrollBuffer', SCROLL_BUFFER);
    this.set('term', '');
    this.set('results', {});
    this.set('isLoading', false);
    this.set('isSearchOpen', false);
  },

  didInsertElement() {
    this._super(...arguments);
    this.queryTerm('');

    this.addEventListener(...keyboardListener({
      esc: this.hideSearch
    }));
  },

  hasHits: computed.notEmpty('results.hits'),
  hits: computed.readOnly('results.hits'),
  nextPage: computed('results.page', function() {
    return this.get('results.page') + 1;
  }),

  actions: {
    setTerm(term) {
      this.set('term', term);
      this.queryTerm(term);
    },
    loadMore() {
      let term = this.get('term');
      let nextPage = this.get('nextPage');

      return this.queryTerm(term, nextPage);
    },
    hideSearch() {
      this.hideSearch();
    }
  },

  showSearch() {
    this.set('isSearchOpen', true);
  },

  hideSearch() {
    this.set('isSearchOpen', false);
  },

  mouseEnter() {
    this.showSearch();
  },

  mouseLeave() {
    this.hideSearch();
  },

  focusIn() {
    this.showSearch();
  },

  queryTerm(term, page = 0) {
    if (this.get('isLoading')) {
      return RSVP.Promise.resolve();
    }

    let search = this.get('search');
    let options = term === '' ? assign({}, EMPTY_TERM_OPTIONS) : assign({}, TERM_OPTIONS);

    options['facetFilters'] = `broadcaster_login:${this.get('ownerLogin')}`;
    options['page'] = page;

    this.set('isLoading', true);
    return search.queryForType('videos', term, options).then((results) => {
      if (this.isDestroyed) { return; }
      this.set('results', results[VIDEO_TYPE]);
    }).catch(error => {
      throw error;
    }).finally(() => {
      if (this.isDestroyed) { return; }
      this.set('isLoading', false);
    });
  }
});
