/* globals i18n */

import Ember from 'ember';
import Component from 'ember-component';
import computed from 'ember-computed';
import { assign as merge } from 'ember-platform';
import injectService from 'ember-service/inject';
import $ from 'jquery';
import RSVP from 'rsvp';
const { PromiseProxyMixin } = Ember;

const FOLLOW_EVENT = 'follow';
const UNFOLLOW_EVENT = 'unfollow';

/**
 * Follow Button Component.
 * All options:
 *  - `channel` - The only required parameter, a channel object that contains at
 *                minimum an `id`.
 *  - `text` - Customize the text. You can use `{{channel}}` to render the channel
 *          name.
 *  - `track` - An action to track a follow. See
 *              [the implementation][tracking_implementation] to see what
 *              parameters are passed to the action.
 *  - `name` - a name for the follow button, passed to the `track` action.
 *  - `type` - `signup` or `login`, to determine what kind of modal to display
 *             when an unauthenticated user clicks.
 *  - `channel.display_name` - passed to the `onFailedAuthentication` function.
 **/
export default Component.extend(PromiseProxyMixin, {
  store: injectService(),
  session: injectService(),

  tagName: '',

  // Public interface
  channel: null,
  vodId: null,
  vodType: null,
  text: 'Follow',
  type: 'login',
  hosterChannelId: '',
  // useful to identify different buttons for tracking.
  name: 'follow_button',
  onClick() {},
  includeTrackingData() { return {}; },

  _text: computed('text', 'channelDisplayName', function () {
    let text = this.get('text');
    let channel = this.get('channelDisplayName');

    if (i18n) {
      text = i18n(text);
    }

    return text.replace(/{{channel}}/g, channel);
  }),

  isLoggedIn: computed.readOnly('session.isAuthenticated'),
  isLoggedOut: computed.not('isLoggedIn'),
  isFollowLoaded: computed.bool('follow'),
  isFollowing: computed.readOnly('follow.isFollowing'),
  isInitialized: computed.or('isLoggedOut', 'isFollowLoaded'),
  isLoadingFollow: computed.readOnly('follow.isLoading'),

  channelDisplayName: computed('channel.id', 'channel.display_name', function () {
    return this.get('channel.id') || this.get('channel.display_name');
  }),

  follow: computed('channel.id', 'isLoggedIn', function () {
    let channel = this.get('channel.id');
    let isLoggedIn = this.get('isLoggedIn');

    if (!channel || !isLoggedIn) {
      return null;
    }

    let store = this.get('store');
    return store.findRecord('follow', channel);
  }),

  currentAction: computed('isLoggedIn', function () {
    return this.get('isLoggedIn') ? 'toggleFollowing' : 'onFailedAuthentication';
  }),

  actions: {
    toggleFollowing() {
      let data = merge({}, this.get('includeTrackingData')());
      this.get('onClick')();

      let follow = this.get('follow.content');
      if (!follow) {
        return RSVP.reject();
      }

      follow.toggleProperty('isFollowing');
      return follow.save().then(() => {
        if (this.isDestroyed) { return; }
        let eventName = this.get('isFollowing') ? FOLLOW_EVENT : UNFOLLOW_EVENT;

        data = merge(data, {
          src: this.get('name'),
          channel: this.get('channel.id'),
          game: this.get('channel.game'),
          notifications: false,
          vod_id: this.get('vodId') || null,
          vod_type: this.get('vodType') || null
        });

        if (this.get('name') === 'host_mode') {
          data.host_channel = this.get('hosterChannelId');
        }

        this.sendAction('track', eventName, this.get('channel'), data);
      });
    },

    onFailedAuthentication() {
      $.showAuthenticationOverlay(this.get('type'), {
        mpSourceAction: 'follow-button',
        follow: this.get('channelDisplayName')
      });
    }
  }
});
