import Component from 'ember-component';
import injectService from 'ember-service/inject';
import computed from 'ember-computed';
import { assign } from 'ember-platform';
import moment from 'moment';
import RSVP from 'rsvp';
import { TYPES, VIDEO_TYPE } from 'web-client/services/search';

const SCROLL_BUFFER = 500;
const HITS_PER_PAGE = 10;
const EMPTY_TERM_OPTIONS = {
  indexName: TYPES[VIDEO_TYPE].indexName,
  hitsPerPage: HITS_PER_PAGE
};

const TERM_OPTIONS = {
  hitsPerPage: HITS_PER_PAGE
};

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

  addItemToPlaylist() {},
  doneHandler() {},
  removeItemFromPlaylist() {},

  creatorId: '',
  isLoading: false,
  playlistItemIds: null,
  scrollBuffer: SCROLL_BUFFER,
  searchTerm: '',
  showCreatorVideos: true,

  init() {
    this._super(...arguments);
    this.set('results', {});

    if (!this.get('playlistItemIds')) {
      this.set('playlistItemIds', []);
    }
  },

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

  searchResults: computed('results.hits', function() {
    let searchVideos = this.get('results.hits');
    if (!searchVideos || searchVideos.length === 0) {
      return [];
    }

    let store = this.get('store');
    let videoSerializer = store.serializerFor('video');

    return searchVideos.map((video) => {
      video = normalizeCreatedAt(video);
      return videoSerializer.normalizeSearchResult(video);
    });
  }),

  hasResults: computed.notEmpty('searchResults'),

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

  actions: {
    loadMore() {
      let searchTerm = this.get('searchTerm');
      let nextPage = this.get('nextPage');
      return this.queryTerm(searchTerm, nextPage);
    },
    setSearchTerm(searchTerm) {
      this.set('searchTerm', searchTerm);
      this.queryTerm(searchTerm);
    },
    showCreatorVideos(isCreator) {
      this.set('showCreatorVideos', isCreator);
      this.set('results', {});
    }
  },

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

    let options = searchTerm === '' ? assign({}, EMPTY_TERM_OPTIONS) : assign({}, TERM_OPTIONS);
    options['page'] = page;

    if (this.get('showCreatorVideos')) {
      options['facetFilters'] = `broadcaster_id:${this.get('creatorId')}`;
    }

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

const normalizeCreatedAt = (item) => {
  // Search service returns a unix timestamp, however the video model expects
  // a string for createdAt that's an rfc3339 formatted date which should be
  // the default format as of 2.13.0

  // Because results are built up in the same object over time, only parse
  // new results which are still numbers
  if (typeof item.created_at === 'number') {
    item.created_at = moment.unix(item.created_at).format();
  }
  return item;
};
