import Component from 'ember-component';
import ContextBoundTasksMixin from 'web-client/mixins/context-bound-tasks';
import OnsiteNotificationTracking from 'web-client/mixins/onsite-notifications/tracking';
import injectService from 'ember-service/inject';
import urlParams from 'web-client/utilities/url-params';
import EmberObject from 'ember-object';
import $ from 'jquery';
import { A as emberA } from 'ember-array/utils';
import run from 'ember-runloop';
import { ONSITE_TYPE, QUICK_REPLY_TYPE } from 'web-client/utilities/toast';
import moment from 'moment';
import { TOAST_DATA } from 'web-client/utilities/onsite-notifications/data';

let useTestData = urlParams.onsite_test_data === "1";

const MAX_TOASTS = 3;
const TOAST_TIMEOUT = 10 * 1000;

// Manages toasts and quick replies
export default Component.extend(ContextBoundTasksMixin, OnsiteNotificationTracking, {
  onsite: injectService('onsite-notifications'),
  conversations: injectService('twitch-conversations/conversations'),
  store: injectService(),

  timers: null,
  toasts: null,

  init() {
    this._super(...arguments);

    this.set('timers', {});
    this.set('toasts', emberA());
    this.get('onsite').bindNewNotification(this, this._handleNewNotification);
    this.get('conversations').on('quickReply', this, this._handleQuickReply);
  },

  didInsertElement() {
    if (useTestData) {
      let testOnsiteNotifications = this._initTestData();
      testOnsiteNotifications.forEach(notification => {
        let toast = this._createToastWrap(notification, ONSITE_TYPE);
        this.get('toasts').unshiftObject(toast);
      });
    }
  },

  willDestroyElement() {
    this._super(...arguments);
    this.get('onsite').unbindNewNotification(this, this._handleNewNotification);
    this.get('conversations').off('quickReply');
  },

  _createToastWrap(content, type) {
    return EmberObject.create({
      content,
      type,
      isPersistent: false
    });
  },

  _handleNewNotification(notification) {
    this._handleNewToast(notification, ONSITE_TYPE);
  },

  _handleQuickReply(thread) {
    if ($('.sc')) {
      this._handleNewToast(thread, QUICK_REPLY_TYPE);
    }
  },

  _handleNewToast(content, type) {
    let toasts = this.get('toasts');
    let numToasts = toasts.get('length');
    let toast = this._createToastWrap(content, type);
    let toastId = toast.get('content.id');
    let existingToast = this.get('toasts').findBy('content.id', toastId);

    if (!existingToast) {
      if (numToasts >= MAX_TOASTS) {
        for (let i = numToasts - 1; i >= 0; i--) {
          if (!toasts.objectAt(i).get('isPersistent')) {
            toasts.removeAt(i);
            break;
          }
        }
      }

      return this._addToast(toast);
    }

    // Onsite toasts should requeue if existing and not currently hovered over
    if (type === ONSITE_TYPE && !existingToast.get('isPersistent')) {
      return this._requeueToast(toast);
    }
  },

  _removeToast(toast, shouldRequeue=false) {
    let toastId = toast.get('content.id');

    this._deleteToastTimer(toast);
    let freshToasts = this.get('toasts').rejectBy('content.id', toastId);
    if (shouldRequeue) {
      this._setToastTimer(toast);
      freshToasts.unshiftObject(toast);
    }
    this.set('toasts', freshToasts);
  },

  _addToast(toast) {
    this._setToastTimer(toast);
    this.get('toasts').unshiftObject(toast);
  },

  _requeueToast(toast) {
    this._removeToast(toast, true);
  },

  _setToastTimer(toast) {
    let toastId = toast.get('content.id');
    let timers = this.get('timers');

    timers[toastId] = run.later(this, function() {
      this._removeToast(toast);
    }, TOAST_TIMEOUT);
  },

  _deleteToastTimer(toast) {
    let toastId = toast.get('content.id');
    let timers = this.get('timers');

    if (timers[toastId]) {
      run.cancel(timers[toastId]);
      delete timers[toastId];
    }
  },

  actions: {
    clickNotification(toast) {
      this.sendAction('clickNotification', toast.get('content'), 'toast');
      this._removeToast(toast);
    },

    close(toast) {
      this.trackNotificationInteraction('dismiss', 'toast', toast.get('content'));
      this._removeToast(toast);
    },

    cancelTimer(toast) {
      let toastId = toast.get('content.id');
      let timer = this.get('timers')[toastId];
      if (timer) {
        this._deleteToastTimer(toast);
        toast.set('isPersistent', true);
      }
    },

    startTimer(toast) {
      let toastId = toast.get('content.id');
      let timer = this.get('timers')[toastId];
      if (!timer) {
        this._setToastTimer(toast);
        toast.set('isPersistent', false);
      }
    }
  },

  _initTestData() {
    let i = 3;
    return TOAST_DATA.map((payload) => {
      payload.updated_at = moment().subtract(i, 'seconds').toISOString();
      i += 5;
      this.get('store').pushPayload('onsite-notification', payload);
      return this.get('store').peekRecord('onsite-notification', payload.id);
    });
  }

});
