import Component from 'ember-component';
import BadgeSetModel from 'web-client/models/badge-set';
import computed from 'ember-computed';
import run, { scheduleOnce } from 'ember-runloop';
import injectService from 'ember-service/inject';
import observer from 'ember-metal/observer';
import { htmlSafe } from 'ember-string';
import { assert } from 'ember-metal/utils';
import InteractivityDeferredComponent from 'web-client/mixins/interactivity-deferred-component';

export default Component.extend(InteractivityDeferredComponent, {
  chatService: injectService('vod-chat-service'),

  video: null,
  messages: computed.alias('chatService.messages'),
  videoStartedAt: computed.alias('chatService.video.recorded_at'),

  init() {
    this._super(...arguments);
    assert(`Video should be set for ${this}`, this.get('video'));

    this.get('chatService').setVideo(this.get('video'));

    let channelName = this.get('video.channel.name');
    if (channelName) {
      this.set('badgeSet', BadgeSetModel.findOne(channelName).load());
    }
  },

  didInsertElement() {
    this._scrollEvents = `scroll.${this.elementId} mousedown.${this.elementId} wheel.${this.elementId} DOMMouseScroll.${this.elementId} mousewheel.${this.elementId} keyup.${this.elementId}`;
    this.set('chatMessagesScroller', this.$('.js-chat-messages .tse-scroll-content'));
    this._initScroller();
    this._prepareOnChatMessageInsert();
    this._prepareStickyBottom();
    scheduleOnce('afterRender', this, this.reportInteractive);
  },

  willDestroyElement() {
    if (this.$('.js-chat-messages').data('plugin_TrackpadScrollEmulator')) {
      this.$('.js-chat-messages').TrackpadScrollEmulator('destroy');
    }
    let scroller = this.get('chatMessagesScroller');
    scroller.off(this._scrollEvents);
  },

  willDestroy() {
    this._super(...arguments);
    this.get('chatService').clearVideo();
  },

  didUpdateAttrs() {
    this.get('chatService').setVideo(this.get('video'));
  },

  badgeStyle: computed('badgeSet.subscriber.image', function() {
    let image = this.get('badgeSet.subscriber.image');
    return htmlSafe(`<style>.badge.subscriber { background-image: url("${image}"); }</style>`);
  }),

  _initScroller() {
    this.$('.js-chat-messages').TrackpadScrollEmulator({
      wrapContent: false,
      scrollbarHideStrategy: 'rightAndBottom'
    });
  },

  _scheduleScrollToBottom() {
    this.throttleTask('_scrollToBottom', 300);
  },

  _scrollToBottom() {
    let scroller = this.get('chatMessagesScroller');

    this.runTask(() => {
      if (scroller && scroller.length) {
        scroller.scrollTop(scroller[0].scrollHeight);
        this._setStuckToBottom(true);
      }
    });
  },

  _setStuckToBottom(stuckToBottom) {
    this.set('stuckToBottom', stuckToBottom);
    this.set('chatService.stuckToBottom', stuckToBottom);
  },

  _prepareStickyBottom() {
    let scroller = this.get('chatMessagesScroller'),
        STUCK_TO_BOTTOM_THRESHOLD = 10;
    this._setStuckToBottom(true);
    /** Differentiating user scroll vs JavaScript scroll: http://stackoverflow.com/questions/2834667 */
    scroller.on(this._scrollEvents, e => {
      if (scroller && scroller[0] && (e.which > 0 || e.type === 'mousedown' || e.type === 'mousewheel')) {
        let scrollDistanceToBottom = scroller[0].scrollHeight - scroller[0].scrollTop - scroller[0].offsetHeight;
        run(() => {
          this._setStuckToBottom(scrollDistanceToBottom <= STUCK_TO_BOTTOM_THRESHOLD);
        });
      }
    });
  },

  _prepareOnChatMessageInsert: observer('messages.[]', function() {
    if (this.get('stuckToBottom')) {
      this._scheduleScrollToBottom();
    }
  }),

  actions: {
    scrollToBottom() {
      this._scheduleScrollToBottom();
    },

    deleteMessage(id) {
      this.get('chatService').deleteMessage(id);
    }
  }
});
