/* We are purposefully not using computed properties here.
 * Please be very careful when accessing data as it likely won't be bound
 * Please ask the chat team if you have any questions
*/

import Component from 'ember-component';

import Ember from 'ember';
import injectService from 'ember-service/inject';
import { tokenizeBits } from 'web-client/utilities/bits/tokenize';
import {
  linkifyMessage,
  mentionizeMessage,
  emoticonizeMessage,
  finalizeTokens,
  getTime,
  tokenizeRichContent
} from 'web-client/helpers/chat/chat-line-helpers';
import { htmlSafe } from 'ember-string';
import getter from 'web-client/utilities/getter';

const { Handlebars } = Ember;
const { escapeExpression } = Handlebars.Utils;

export const BADGE_PROPERTIES = {
  isBroadcaster: {
    tooltip: 'Broadcaster',
    cssClass: 'broadcaster'
  },
  showStaffBadge: {
    tooltip: 'Twitch Staff',
    cssClass: 'staff'
  },
  showAdminBadge: {
    tooltip: 'Twitch Admin',
    cssClass: 'admin'
  },
  showGlobalModBadge: {
    tooltip: 'Twitch Global Moderator',
    cssClass: 'global-moderator'
  },
  showModeratorBadge: {
    tooltip: 'Moderator',
    cssClass: 'moderator'
  },
  isSubscriber: {
    tooltip: 'Subscriber',
    cssClass: 'subscriber'
  },
  hasTurbo: {
    tooltip: 'Turbo',
    cssClass: 'turbo'
  }
};

export default Component.extend({
  // public things
  msgObject: undefined,
  isChannelLinksDisabled: false,
  currentUserNick: undefined,
  isViewerModeratorOrHigher: false,
  isTwitchPrivilegedUser:false,
  enableLinkification: true,
  globals: injectService(),
  bitsEmotes: injectService(),
  bitsTags: injectService(),

  isBitsVisibleBecauseStaff: getter(function () {
    return this.get('isStaff') && this.get('globals.isBitsStaffOnlyBeta');
  }),
  isBitsEnabled: getter(function () {
    return this.get('globals.isBitsEnabled') || this.get('isBitsVisibleBecauseStaff');
  }),
  isBits: getter(function () {
    return this.get('msgObject.tags.bits');
  }),
  isWhisper: getter(function () {
    return this.get('msgObject.style') === 'whisper';
  }),

  canRenderBits: getter(function () {
    return this.get('bitsEmotes.isLoaded') && this.get('isBits') && this.get('isBitsEnabled');
  }),

  /** Transforms a message into a token array processed by all emoticons available to the sender. */
  tokenizedMessage: getter(function () {
    let tokens = [this.get('msgObject.message')],
        hideChatLinks = this.get('hideChatLinks'),
        userNick = this.get('currentUserNick'),
        userDisplayname = this.get('currentUserDisplayname'),
        isOwnMessage = this.get('msgObject.from') === userNick,
        emoticons = this.get('msgObject.tags.emotes');

    let richContent = this.get('msgObject.tags.content');

    if (this.get('canRenderBits')) {
      tokens = tokenizeBits(tokens, this.get('bitsTags.allTagNames'), this.get('bitsEmotes.regexes'));
    }
    tokens = tokenizeRichContent(tokens, richContent, hideChatLinks); // Must occur before linkification
    if (this.get('enableLinkification')) {
      tokens = linkifyMessage(tokens, hideChatLinks);
    }

    tokens = mentionizeMessage(tokens, userNick, isOwnMessage);
    tokens = mentionizeMessage(tokens, userDisplayname, isOwnMessage);
    tokens = emoticonizeMessage(tokens, emoticons);
    return finalizeTokens(tokens);
  }),

  colorStyle(color) {
    if (color) {
      return `color:${escapeExpression(color)}`;
    }
    return '';
  },

  fromStyle: getter(function () {
    return htmlSafe(this.colorStyle(this.get('msgObject.color')));
  }),

  messageStyle: getter(function () {
    if (this.get('msgObject.style') === 'action') {
      return this.get('fromStyle');
    }
    return htmlSafe('');
  }),

  timestamp: getter(function () {
    if (this.get('msgObject.date')) {
      return getTime(this.get('msgObject.date'));
    }
  }),

  // TODO: Use msgObject.tags.user-type rather than labels. Requires updates in TMI.js first.
  isBroadcaster: getter(function () {
    return (this.get('msgObject.labels') || []).indexOf('owner') >= 0;
  }),

  isStaff: getter(function () {
    return (this.get('msgObject.labels') || []).indexOf('staff') >= 0;
  }),

  isAdmin: getter(function () {
    return (this.get('msgObject.labels') || []).indexOf('admin') >= 0;
  }),

  isGlobalMod: getter(function () {
    return (this.get('msgObject.labels') || []).indexOf('global_mod') >= 0;
  }),

  isSubscriber: getter(function () {
    return (this.get('msgObject.labels') || []).indexOf('subscriber') >= 0;
  }),

  isModerator: getter(function () {
    return (this.get('msgObject.labels') || []).indexOf('mod') >= 0;
  }),

  isTmiMessage: getter(function () {
    return this.get('msgObject.style') === 'admin';
  }),

  isModeratorOrHigher: getter(function () {
    return this.get('isBroadcaster') || this.get('isStaff') || this.get('isAdmin') || this.get('isGlobalMod') || this.get('isModerator') || this.get('isTmiMessage');
  }),

  hideChatLinks: getter(function () {
    return !this.get('isModeratorOrHigher') && this.get('isChannelLinksDisabled');
  }),

  showStaffBadge: getter(function () {
    let isBroadcaster = this.get('isBroadcaster'),
        isStaff = this.get('isStaff');
    return !isBroadcaster && isStaff;
  }),

  showAdminBadge: getter(function () {
    let isBroadcaster = this.get('isBroadcaster'),
        isStaff = this.get('isStaff'),
        isAdmin = this.get('isAdmin');
    return !isBroadcaster && !isStaff && isAdmin;
  }),

  showGlobalModBadge: getter(function () {
    let isBroadcaster = this.get('isBroadcaster'),
        isGlobalMod = this.get('isGlobalMod');
    return !isBroadcaster && isGlobalMod;
  }),

  showModeratorBadge: getter(function () {
    let isBroadcaster = this.get('isBroadcaster'),
        isModerator = this.get('isModerator');
    return !isBroadcaster && isModerator;
  }),

  hasTurbo: getter(function () {
    return (this.get('msgObject.labels') || []).indexOf('turbo') >= 0;
  }),

  hasTurboTag: getter(function () {
    return !!this.get('msgObject.tags.turbo');
  }),

  moderationTarget: getter(function () {
    return {user: this.get('msgObject.from')};
  }),

  actions: {
    clickTurbo() {
      window.open('/products/turbo?ref=chat_badge', '_blank');
    }
  }

});
