import Component from 'ember-component';
import injectService from 'ember-service/inject';
import computed from 'ember-computed';
import extractResponseErrorMessage from 'web-client/utilities/extract-response-error-message';

import { CREATIVE, CREATIVE_GAME_COMMUNITY_MAPPING } from 'web-client/utilities/game-names';

export const MAX_TITLE_LENGTH = 140;
const BALLOON_NOTIFICATION_DURATION_MS = 2000;
const UNABLE_TO_BROADCAST_TO_COMMUNITY = 'You are unable to broadcast to that community.';
const BANNED_FROM_COMMUNITY = 'You have been banned from this Community';
const TIMED_OUT_FROM_COMMUNITY =  'You have been timed out from this Community';
const CHANNEL_BANNED_FROM_COMMUNITY = "channel_banned_from_community";
const CHANNEL_TIMED_OUT_FROM_COMMUNITY = "channel_timed_out_from_community";


export default Component.extend({
  tagName: 'form',
  classNames: ['js-dashboard-edit-broadcast'],

  globals: injectService(),
  store: injectService(),
  session: injectService(),
  tracking: injectService(),

  /* for communities */
  communities: injectService(),

  /* passed in properties */
  channel: null,
  trackDashboardEvent() {},

  /* internal properties */
  community: null,
  communityName: '',
  isErrored: false,
  isSuccess: false,
  isBlcCheckboxDisabled: false,
  isInvalidGame: false,
  isGamePending: false,
  isInvalidCommunity: false,
  communityError: '',

  title: computed.oneWay('channel.status'),

  isTitleError: computed.gt('title.length', MAX_TITLE_LENGTH),

  titleCharsRemaining: computed('title.length', function() {
    let characterCount = this.get('title.length');

    return characterCount ? MAX_TITLE_LENGTH - characterCount : MAX_TITLE_LENGTH;
  }),

  game: computed.oneWay('channel.game'),

  isPlaying: computed.notEmpty('game'),

  broadcasterLanguage: computed.oneWay('channel.broadcasterLanguage'),

  languageOptions: computed(function() {
    let allowedLanguagesMap = this.get('globals').broadcasterLanguages;

    return Object.keys(allowedLanguagesMap).map(languageCode => {
      return {
        code: languageCode,
        name: allowedLanguagesMap[languageCode]
      };
    });
  }),

  isInvalidLanguage: computed('broadcasterLanguage', function() {
    let allowedLanguagesMap = this.get('globals').broadcasterLanguages;
    let selectedLanguage = this.get('broadcasterLanguage');

    return !allowedLanguagesMap.hasOwnProperty(selectedLanguage);
  }),

  isChatLanguageRestricted: computed.oneWay('channel.room.restrictedChatLanguage'),

  isUpdateDisabled: computed.or('channel.isSaving', 'isTitleError', 'isInvalidLanguage', 'isInvalidGame', 'isGamePending', 'isInvalidCommunity'),

  actions: {
    updateBroadcast() {
      let channel = this.get('channel');
      let isUpdateSuccessful = null;

      if (!this.get('isUpdateDisabled')) {
        channel.set('status', this.get('title'));
        channel.set('community', this.get('community.name'));
        channel.set('game', this.get('game'));
        channel.set('broadcasterLanguage', this.get('broadcasterLanguage'));
        channel.set('isLanguageRestricted', this.get('isChatLanguageRestricted'));

        channel.save()
          .then(() => {
            if (this.isDestroyed) { return; }

            isUpdateSuccessful = true;
            this.set('isSuccess', true);
            this.runTask(() => this.set('isSuccess', false), BALLOON_NOTIFICATION_DURATION_MS);
          }, () => {
            if (this.isDestroyed) { return; }

            isUpdateSuccessful = false;
            this.set('isErrored', true);
            this.runTask(() => this.set('isErrored', false), BALLOON_NOTIFICATION_DURATION_MS);
          })
          .finally(() => {
            if (this.isDestroyed) { return; }

            let trackDashboardEvent = this.get('trackDashboardEvent');

            trackDashboardEvent('live_dashboard_stream_information', {
              action: 'click',
              target_name: 'update',
              update_successful: isUpdateSuccessful
            });
          });

        this.updateCommunityBroadcast()
          .then(() => {
            if (this.isDestroyed) { return; }

            this.set('isInvalidCommunity', false);
            this.set('communityError', '');
          }, (err) => {
            if (this.isDestroyed) { return; }

            let responseMessage = extractResponseErrorMessage(err);
            let errorMessage = UNABLE_TO_BROADCAST_TO_COMMUNITY;
            if(responseMessage.match(CHANNEL_BANNED_FROM_COMMUNITY)) {
              errorMessage = BANNED_FROM_COMMUNITY;
            }
            if(responseMessage.match(CHANNEL_TIMED_OUT_FROM_COMMUNITY)) {
              errorMessage =  TIMED_OUT_FROM_COMMUNITY;
            }
            this.set('isInvalidCommunity', true);
            this.set('communityError', errorMessage);
          });
      }
    },

    communityChange() {
      let communityName = this.get('communityName');
      this.set('communityError', '');
      this.set('isInvalidCommunity', false);

      if (!communityName) {
        this.set('community', null);
        return this.trackCommunitySelect(null);
      }
      if(communityName.length < 3) { return this.set('isInvalidCommunity', true);}

      this.get('communities').getCommunityInfo(communityName).then((result) => {
        if (this.isDestroyed) { return; }

        if(result.name !== this.get('community.name')) {
          this.trackCommunitySelect(result);
        }

        this.set('community', result);
        return this.set('isInvalidCommunity', false);
      }, () => {
        if (this.isDestroyed) { return; }

        this.set('community', null);
        this.set('isInvalidCommunity', true);
      });
    },

    languageChange(value) {
      this.set('broadcasterLanguage', value);

      if (value === 'other') {
        this.set('isBlcCheckboxDisabled', true);
        this.set('isChatLanguageRestricted', false);
      } else {
        this.set('isBlcCheckboxDisabled', false);
      }
    },

    removeError() {
      this.set('isErrored', false);
    },

    removeSuccess() {
      this.set('isSuccess', false);
    },

    onGameResolved(game) {
      // If the game is changed to either "Programming" or "Game Development",
      // then the game is changed to "Creative", and the respective hashtag
      // is appended to the title if it is not already present.
      if (CREATIVE_GAME_COMMUNITY_MAPPING.hasOwnProperty(game.name)) {
        let titleSegments = [];
        let existingTitle = this.get('title') || '';
        let hashtag = CREATIVE_GAME_COMMUNITY_MAPPING[game.name];

        if (existingTitle.length) {
          titleSegments.push(existingTitle);
        }

        if (existingTitle.indexOf(hashtag) === -1) {
          titleSegments.push(hashtag);
        }

        this.set('title', titleSegments.join(' '));
        this.set('game', CREATIVE);
      } else {
        this.set('game', game.name);
      }

      this.set('isInvalidGame', !game.id && game.name !== '');
      this.set('isGamePending', false);
    }
  },

  updateCommunityBroadcast() {
    if(this.get('community')) {
      return this.get('communities').broadcastToCommunity(this.get('session.userData.id'), this.get('community._id'));
    }
    return this.get('communities').removeCurrentCommunity(this.get('session.userData.id'));
  },

  trackCommunitySelect(community) {
    let trackingObject = this._getTrackingObject(community);
    this.get('tracking').trackEvent({
      services: ['spade'],
      event: 'community_stream_select',
      data: trackingObject
    });
  },

  _getTrackingObject(community) {
    return {
      community_id: community ? community._id : undefined,
      community_name: community ? community.name : undefined,
      login: this.get('session.userData.login'),
      channel: this.get('session.userData.login'),
      is_live: this.get('channel.stream.isLoaded') && !this.get('channel.stream.isOffline')
    };
  }

});
