import Ember from 'ember';
import Component from 'ember-component';
import InteractivityDeferredComponent from 'web-client/mixins/interactivity-deferred-component';
import injectService from 'ember-service/inject';
import computed from 'ember-computed';
import SendRouteActionMixin from 'web-client/mixins/send-route-action';
import run from 'ember-runloop';


const { Logger } = Ember;
const LIMIT_FOLLOWS_PER_REQUEST = 20;

export default Component.extend(InteractivityDeferredComponent, SendRouteActionMixin, {
  api: injectService(),
  streams: injectService(),
  session: injectService(),

  isLoadingStreams: true,
  watchNowStreams: null,
  failedToLoadStreams: false,

  isFollowingLiveStreamsVisible: true,
  isFollowingOfflineChannelsVisible: computed.not('isFollowingLiveStreamsVisible'),

  isLoggedIn: computed.readOnly('session.isAuthenticated'),

  isLoadingFollowedChannels: false,
  followedChannels: null,

  followingStreams: computed('watchNowStreams', function() {
    return this.get('watchNowStreams').filter((rec) => { return rec.recommendation.reason === 'following'; });
  }).readOnly(),

  recommendedStreams: computed('watchNowStreams', function() {
    return this.get('watchNowStreams').filter((rec) => { return rec.recommendation.reason !== 'following'; });
  }).readOnly(),

  followedOfflineChannels: computed('followedChannels', 'followingStreams', function() {
    // filter out any following channels where we have streams
    let streamsMap = {};
    this.get('followingStreams').forEach(rec => {
      streamsMap[rec.stream.channel.name] = true;
    });
    return this.get('followedChannels').filter(channel => {
      return !streamsMap[channel.name];
    });
  }).readOnly(),

  init() {
    this._super(...arguments);
    this.set('watchNowStreams', []);
    this.set('followedChannels', []);

    this._hasLoadedFollowedChannels = false;
    this._loadFollowedChannelsPromise = null;
    this._loadFollowedChannelsOffset = 0;
    this._knownFollows = {};

    this.get('streams').getWatchNowStreams().then((response) => {
      if (this.isDestroyed) { return; }
      this.set('watchNowStreams', response.recommendations || []);
    }, () => {
      if (this.isDestroyed) { return; }
      this.set('failedToLoadStreams', true);
    }).finally(() => {
      if (this.isDestroyed) { return; }
      this.set('isLoadingStreams', false);
      run.scheduleOnce('afterRender', this, this.reportInteractive);
    });
  },

  actions: {
    showFollowingLiveStreams() {
      this.set('isFollowingLiveStreamsVisible', true);
    },
    showFollowingOfflineChannels() {
      this.set('isFollowingLiveStreamsVisible', false);
      if (!this._hasLoadedFollowedChannels) {
        this._hasLoadedFollowedChannels = true;
        this._loadFollowedChannelsAPI();
      }
    },
    showLogin() {
      this.sendRouteAction('handleLoginButtonClick');
    },
    showSignup() {
      this.sendRouteAction('handleSignupButtonClick');
    },
    loadMoreFollowedChannels() {
      this._loadFollowedChannelsAPI();
    }
  },

  _loadFollowedChannelsAPI() {
    if (!this.get('isLoggedIn')) {
      return;
    }
    if (this._loadFollowedChannelsPromise !== null) {
      return;
    }

    this.set('isLoadingFollowedChannels', true);
    let user = this.get('session.userData');
    let url = `/kraken/users/${user.id}/follows/channels`;
    let opts = {
      version: 5
    };
    let params = {
      offset: this._loadFollowedChannelsOffset,
      limit: LIMIT_FOLLOWS_PER_REQUEST
    };

    this._loadFollowedChannelsPromise = this.get('api').authRequest('get', url, params, opts).then(response => {
      if (this.isDestroyed) { return; }
      this._loadFollowedChannelsOffset += LIMIT_FOLLOWS_PER_REQUEST;

      let follows = this.get('followedChannels');
      response.follows.forEach(follow => {
        let channel = follow.channel;
        if (!this._knownFollows.hasOwnProperty(channel.name)) {
          this._adaptChannelForTemplate(channel);
          this._knownFollows[channel.name] = channel;
          follows.push(channel);
        }
      });
      this.set('followedChannels', follows);
      this.notifyPropertyChange('followedChannels');
    }, (err) => {
      Logger.error("Failed to fetch right-column followed channels:", err);
      if (this.isDestroyed) { return; }
      this.set('failedLoadingFollowedChannels', true);
    }).finally(() => {
      if (this.isDestroyed) { return; }
      this.set('isLoadingFollowedChannels', false);
      this._loadFollowedChannelsPromise = null;
    });
  },

  _adaptChannelForTemplate(channel) {
    channel.id = channel.name;
    channel.displayName = channel.display_name;
  }
});
