/* globals Twitch */
import Route from 'ember-route';
import RSVP from 'rsvp';
import injectService from 'ember-service/inject';
import { debounce } from 'ember-runloop';

import TrackBttv from 'web-client/mixins/track-bttv';

// These incoming routes are from the old channel page.  Redirect them to new routes.
const REDESIGNED_REDIRECTS = {
  'profile.index':            'channel.videos',
  'profile.following':        'channel.following',
  'profile.followers':        'channel.followers',
  'profile.pastBroadcasts':   'channel.videos',
  'profile.highlights':       'channel.videos'
};

export default Route.extend(TrackBttv, {
  layout: injectService(),
  channelVideosTab: injectService(),
  vodGameInfo: injectService(),
  pubsub: injectService(),
  tracking: injectService(),
  gameSettings: injectService(),
  clips: injectService(),
  collections: injectService(),

  beforeModel(transition) {
    this._super(...arguments);

    let redirectTarget = REDESIGNED_REDIRECTS[transition.targetName];

    if (redirectTarget !== undefined) {
      if (this.router.isFirstTransition) {
        this.replaceWith(redirectTarget);
      } else {
        this.transitionTo(redirectTarget);
      }
    }

    return RSVP.all([
      this.get('channelVideosTab').checkExperiment(),
      this.get('vodGameInfo').checkExperiment(),
      this.get('clips').checkClipsTabExperiment(),
      this.get('collections').checkPlaylistTabExperiment()
    ]);
  },

  model() {
    return this.modelFor('user');
  },

  afterModel(model) {
    this._super(...arguments);
    let channelName = model.get('id');
    let channelController = this.controllerFor('channel');

    // Here we fetch the new channel model and store it in "channelModel" on
    // the controller.  Eventually, this will replace the current model() as
    // we migrate to the Ember Data channel model.
    return this.store.findRecord('channel', channelName).then(channel => {
      channelController.set('channelModel', channel);
    }, () => {
      /*
       * No op. by catching error, channel-wrapper will display error message.
       */
    });
  },

  buildPageTitle() {
    let user = this.modelFor('user');
    let isInvalidUser = user.get('notFound') || user.get('unavailable');

    return {
      title: isInvalidUser ? null : user.get('display_name')
    };
  },

  setupController(controller, model) {
    this._super(...arguments);

    this.controllerFor('chat').setCurrentChannelRoom(model.get('id'));
    this.subscribeChannelEvents(model);
  },

  resetController(controller) {
    this.unsubscribeChannelEvents(controller.get('model'));
  },

  activate() {
    this.set('layout.showRightColumn', true);
  },

  deactivate() {
    if (Twitch.user.isLoggedIn()) {
      /* debounce a call to `this.controller.updatePresence(true)` by 1 second */
      debounce(this.controller, this.controller.updatePresence, true, 1000);
    }

    this.set('layout.showRightColumn', false);
    this.disconnectOutlet({
      outlet: 'modal',
      parentView: 'application'
    });
    this.controllerFor('chat').removeCurrentChannelRoom();
  },

  pubsubTopic(model) {
    return model ? `channel.${model.get('id')}` : null;
  },

  subscribeChannelEvents(model) {
    this.get('pubsub').on(this.pubsubTopic(model), this, this.handlePubsub);
  },

  unsubscribeChannelEvents(model) {
    this.get('pubsub').off(this.pubsubTopic(model), this, this.handlePubsub);
  },

  handlePubsub(payload) {
    if (payload.type === 'status') {
      this.controller.set('model.status', payload.status);
    }
  }
});
