import Service from 'ember-service';
import moment from 'moment';
import injectService from 'ember-service/inject';

const FIRST_PAGE = 0;

export const VIDEO_TYPE = 'videos';
const COMMUNITIES_INDEX = 'community';

export const TYPES = {
  'games': {
    indexName: 'game',
    hitsPerPage: 2,
    topNumericFilters: 'popularity>1',
    singleTypeNumericFilters: ''
  },
  [VIDEO_TYPE]: {
    indexName: 'vod',
    hitsPerPage: 6,
    get topNumericFilters() {
      return `created_at>${aMonthAgo()}`;
    },
    singleTypeNumericFilters: ''
  },
  'users': {
    indexName: 'user',
    hitsPerPage: 2,
    topNumericFilters: 'followers>50',
    singleTypeNumericFilters: ''
  },
  'channels': {
    indexName: 'live_channel',
    hitsPerPage: 6,
    get topNumericFilters() {
      return `channel_count>10,updated_on>${recently()}`;
    },
    get singleTypeNumericFilters() {
      return `updated_on>${recently()}`;
    }
  },
  'communities': {
    indexName: COMMUNITIES_INDEX,
    hitsPerPage: 4,
    topNumericFilters: 'popularity>1',
    singleTypeNumericFilters: ''
  }
};

export default Service.extend({
  experiments: injectService(),
  store: injectService(),

  queryTopResults(term) {
    let queryTypes = ['games', 'channels', 'users', VIDEO_TYPE];

    let topResultsParams = queryTypes.map((typeId) => {
      let type = TYPES[typeId];

      return {
        indexName: type.indexName,
        query: term,
        params: {
          page: FIRST_PAGE,
          hitsPerPage: type.hitsPerPage,
          numericFilters: type.topNumericFilters
        }
      };
    });

    let totalResultsParams = queryTypes.map((typeId) => {
      let type = TYPES[typeId];

      return {
        indexName: type.indexName,
        query: term,
        params: {
          hitsPerPage: 0,
          numericFilters: type.singleTypeNumericFilters
        }
      };
    });

    let params = [].concat(topResultsParams, totalResultsParams);

    return this.get('store').query('search', params).then(() => {
      return searchObject(this.get('store'));
    });
  },

  queryVodsByTag(tag, game, page = FIRST_PAGE, afterCreatedAt = 0) {
    let query = {
      indexName: TYPES[VIDEO_TYPE].indexName,
      query: `"${tag}"`,
      params: {
        hitsPerPage: 30,
        advancedSyntax: true,
        facets: 'game',
        facetFilters: `game:${game}`,
        filters: `created_at > ${afterCreatedAt}`,
        page
      }
    };
    return this.get('store').query('search', [query]);
  },

  queryForType(typeId, term, options = {}) {
    let type = TYPES[typeId];
    let queryParams = [{
      indexName: options.indexName || type.indexName,
      query: term,
      params: {
        page: options.page || FIRST_PAGE,
        hitsPerPage: options.hitsPerPage || 50,
        numericFilters: options.numericFilters || type.singleTypeNumericFilters,
        facets: '*',
        facetFilters: options.facetFilters || ''
      }
    }];

    return this.get('store').query('search', queryParams).then(() => {
      return searchObject(this.get('store'));
    });
  }
});

export function searchObject(store) {
  return {
    games: store.peekRecord('search', 'game'),
    [VIDEO_TYPE]: store.peekRecord('search', TYPES[VIDEO_TYPE].indexName),
    users: store.peekRecord('search', 'user'),
    channels: store.peekRecord('search', 'live_channel'),
    communities: store.peekRecord('search', COMMUNITIES_INDEX)
  };
}

function recently() {
  return moment().subtract(10, 'minutes').unix();
}

function aMonthAgo() {
  return moment().subtract(1, 'month').unix();
}
