import Service from 'ember-service';
import injectService from 'ember-service/inject';
import computed from 'ember-computed';
import RSVP from 'rsvp';

const EXPIRATION_TIME = 1000 * 60 * 5;

export default Service.extend({
  api: injectService(),
  store: injectService(),
  session: injectService(),
  tracking: injectService(),

  recommendationsAvailable: false,
  recommendations: [],
  similarChannels: [],

  showDiscoveryTab: computed.bool('recommendationsAvailable'),

  _findAvailable(oauthToken) {
    let params = { oauth_token: oauthToken };

    return this.get('api').request('get', '/kraken/streams/recommended/available', params).then((response) => {
      if (this.isDestroyed) { return; }

      if (response.has_recommendations === true) {
        this.set('recommendationsAvailable', true);
      }

      return oauthToken;
    }).catch((error) => {
      // Treat api call errors as "no recommendations available"
      if (typeof error === 'object' && error.status >= 400) {
        return;
      }

      throw error;
    });
  },

  _findRecommendations(oauthToken) {
    let store = this.get('store');
    let existingRecommendations = store.peekAll('recommended-stream');

    let isNotExpired = (recommendedStream) => {
      return (Date.now() - recommendedStream.get('fetchedAt') < EXPIRATION_TIME);
    };

    if (existingRecommendations.get('length')) {
      if (existingRecommendations.every(isNotExpired)) {
        this.set("recommendations", existingRecommendations.sortBy('rank'));
        return;
      }

      store.unloadAll('recommended-stream');
    }

    return store.query('recommended-stream', {
      oauth_token: oauthToken
    }).then((newRecommendations) => {
      if (this.isDestroyed) { return; }

      this.set("recommendations", newRecommendations.sortBy('rank'));
    });
  },

  findRecommendations() {
    return new RSVP.Promise((resolve, reject) => {
      let {isAuthenticated, userData} = this.get('session');
      if (isAuthenticated) {
        this._findAvailable(userData.chat_oauth_token).then(() => {
          if (this.isDestroyed) { return; }
          if (this.get('recommendationsAvailable')) {
            return this._findRecommendations(userData.chat_oauth_token);
          }
        }).then(resolve, reject);
      } else {
        resolve();
      }
    });
  },

  getSimilarChannels() {
    return new RSVP.Promise((resolve, reject) => {
      let {isAuthenticated, userData} = this.get('session');
      if (isAuthenticated) {
        let params = { oauth_token: userData.chat_oauth_token };
        this.get('api').request('get', '/kraken/channels/similar', params).then((response) => {
          if (this.isDestroyed) { return; }

          if (response) {
            this.set('similarChannels', response.similar_channels);
          } else {
            this.set('similarChannels', []);
          }
        }).then(resolve, reject);
      } else {
        resolve();
      }
    });
  }
});
