import observer from 'ember-metal/observer';
import Ember from 'ember';
import { libs } from 'web-client/utilities/presence-util';
import Service from 'ember-service';
import Evented from 'ember-evented';
import run from 'ember-runloop';
import computed from 'ember-computed';

const { Logger, inject } = Ember;

export default Service.extend(Evented, {

  globals: inject.service('globals'),

  tagEnabledChannelsString: computed.readOnly('globals.bitsEvoEnabledChannels'),
  tagEnabledChannels: computed('tagEnabledChannelsString', function() {
    if (this.get('tagEnabledChannelsString') !== null && this.get('tagEnabledChannelsString') !== undefined) {
      return this.get('tagEnabledChannelsString').split(',').map(Number);
    }

    return [];
  }),

  channelId: null,

  player1Count: computed('player1CountDb', 'player1CountClient', function() {
    return Math.max(this.get('player1CountDb'), this.get('player1CountClient'));
  }),
  player1CountClient: 0,
  player1CountDb: computed('selectedTags', 'selectedTags.@each.total', 'player1Tag', function() {
    let player1Tag = this.get('player1Tag');
    let player1TagObj = this.get('selectedTags').findBy('hashtag', player1Tag);
    return player1TagObj ? player1TagObj.total : 0;
  }),

  player2Count: computed('player2CountDb', 'player2CountClient', function() {
    return Math.max(this.get('player2CountDb'), this.get('player2CountClient'));
  }),
  player2CountClient: 0,
  player2CountDb: computed('selectedTags', 'selectedTags.@each.total', 'player2Tag', function() {
    let player2Tag = this.get('player2Tag');
    let player2TagObj = this.get('selectedTags').findBy('hashtag', player2Tag);
    return player2TagObj ? player2TagObj.total : 0;
  }),

  isTagEnabledChannel: computed('channelId', function () {
    return this.get('tagEnabledChannels').includes(this.get('channelId'));
  }),

  tags: [],

  selectedTags: computed.filterBy('tags', 'selected', true),

  allTagNames: computed.mapBy('tags', 'hashtag'),

  _oldSelectedTagNames: [],
  selectedTagNames: computed.mapBy('selectedTags', 'hashtag'),
  selectedTagNamesChanged: observer('selectedTagNames', function() {
    let oldTags = this.get('_oldSelectedTagNames');
    let newTags = this.get('selectedTagNames');

    oldTags.sort();
    newTags.sort();
    if (oldTags.join(',') !== newTags.join(',')) {
      this._resetClientCounts();
    }

    this.set('_oldSelectedTagNames', newTags);
  }),


  sufficentTagsForMatch: computed('selectedTagNames', function() {
    return this.get('selectedTagNames').length >= 2;
  }),

  player1Tag: computed('selectedTagNames', function() {
    if(this.get('selectedTagNames').length > 1) {
      return this.get('selectedTagNames')[0];
    }
    return null;
  }),

  player2Tag: computed('selectedTagNames', function() {
    if(this.get('selectedTagNames').length > 1) {
      return this.get('selectedTagNames')[1];
    }
    return null;
  }),

  _parseBitsTagsPayload(data) {
    let payload = [];
    try {
      let pubSubPayload = JSON.parse(data);

      if((pubSubPayload.type !== 'set-hashtag' && pubSubPayload.type !== 'add-hashtag') || (pubSubPayload.msg === undefined)) {
        return;
      }

      payload = JSON.parse(pubSubPayload.msg);
    } catch(e) {
      Logger.error('Failed to parse bits tags payload', data);
      return;
    }

    this.set('tags', payload);
  },

  _resetClientCounts() {
    this.set('player1CountClient', this.get('player1CountDb'));
    this.set('player2CountClient', this.get('player2CountDb'));
  },

  listen() {
    let channelId = this.get('channelId');
    libs.pubsub.Listen({
      topic: `channel-bit-events-public.${channelId}`,
      message: (data) => {
        run(() => {
          this._parseBitsTagsPayload(data);
        });
      }
    });
  },

  _incrementHashtag(tag, amount) {
    tag = tag.toLowerCase();
    if (tag === this.get('player1Tag').toLowerCase()) {
      this.set('player1CountClient', this.get('player1CountClient') + Number(amount));
    } else if (tag === this.get('player2Tag').toLowerCase()) {
      this.set('player2CountClient', this.get('player2CountClient') + Number(amount));
    }
  },

  parseHashtags: function(msg) {
    if (!this.get('sufficentTagsForMatch')) {
      return false;
    }
    let words = msg.message.split(/\s+/);
    let resultTag;
    let found = words.some(function (word) {
      if (word.charAt(0) === '#' && word.length > 1) {
        resultTag = word.substr(1);
        return true;
      }
      return false;
    });
    if (found) {
      this._incrementHashtag(resultTag, msg.tags.bits);
    }
  },

  isChannelTagEnabled(targetChannelId) {
    return this.get('tagEnabledChannels').includes(targetChannelId);
  },

  setupService(targetChannelId) {
    this.set('tags', []);
    this.set('channelId', targetChannelId);
    if (this.get('isTagEnabledChannel')) {
      this.set('channelId', targetChannelId);
      this.listen();
    }
  },

  setTags(hashtags) {
    this.set('tags', hashtags);
  }

});
