import Component from 'ember-component';
import injectService from 'ember-service/inject';
import computed from 'ember-computed';
import ClickOutsideMixin from 'web-client/mixins/click-outside';
import ContextBoundTasksMixin from 'web-client/mixins/context-bound-tasks';
import OnsiteNotificationTracking from 'web-client/mixins/onsite-notifications/tracking';
import OnsiteNotificationClickHandling from 'web-client/mixins/onsite-notifications/click-handling';
import run from 'ember-runloop';

// If there are less than this number of notifications
// when a notification is dismissed, then load more notifications
const DISMISS_THRESHOLD = 7;

// If the unseen view count is over this threshold, then display this threshold
// number plus an addition symbol
const UNSEENVIEWCOUNT_THRESHOLD = 99;

// How long to wait until hiding "X New Notifications"
const NEW_NOTIFICATION_TIMEOUT = 5000;

export default Component.extend(ClickOutsideMixin, ContextBoundTasksMixin, OnsiteNotificationTracking, OnsiteNotificationClickHandling, {
  onsite: injectService('onsite-notifications'),
  layout: injectService(),

  hasViewedCenter: computed.alias('onsite.hasViewedCenter'),
  notifications: computed.readOnly('onsite.notifications'),
  summary: computed.readOnly('onsite.summary'),

  hasUnseen: computed.gt('summary.unseenViewCount', 0),

  unseenViewCount: computed('summary.unseenViewCount', function() {
    let count = this.get('summary.unseenViewCount');
    return count > UNSEENVIEWCOUNT_THRESHOLD ? `${UNSEENVIEWCOUNT_THRESHOLD}+` : count;
  }),

  isCenterOpen: false,

  init() {
    this._super(...arguments);
    this.get('onsite').setupService();
    this.set('newNotificationsCount', 0);
  },

  // for ClickedOutsideMixin
  clickedOutside() {
    if(this.get('isCenterOpen')) {
      this.trackNotificationCenterInteraction('close', this.get('unseenViewCount'));
    }
    this.set('isCenterOpen', false);
  },

  actions: {
    toggleCenter() {
      let onsite = this.get('onsite');

      if (!onsite.get('hasViewedCenter')) {
        // SUPER EDGE CASE: If during an in-flight `loadMoreNotifications`, a new notification
        // is created, and then sent over pubsub, the notification will not be inserted into the center.
        // The window for this is less than a second.
        onsite.loadMoreNotifications();
        onsite.set('hasViewedCenter', true);
      }

      let unseenViewCount = this.get('unseenViewCount');
      if (unseenViewCount > 0) {
        let timerId = this.get('_newNotificationTimer');
        if (timerId) {
          run.cancel(timerId);
        }

        this.set('newNotificationsCount', unseenViewCount);
        timerId = this.runTask(() => {
          this.set('newNotificationsCount', 0);
          this.set('_newNotificationTimer', null);
        }, NEW_NOTIFICATION_TIMEOUT);

        this.set('_newNotificationTimer', timerId);
      }

      let isOpen = this.toggleProperty('isCenterOpen');
      if (isOpen) {
        onsite.setNotificationsCenterViewed();
        this.trackNotificationCenterInteraction('open', unseenViewCount);
      } else {
        this.trackNotificationCenterInteraction('close', unseenViewCount);
      }
    },

    // used by both the `center-window` and `toast-manager` for the primary CTA
    clickNotification(notification, context = 'center') {
      let clickUrl = notification.get('primaryCta.url');
      this.trackNotificationInteraction('primary_cta', context, notification, clickUrl);
      let canTransition = this.routeTo(clickUrl);

      if (!notification.get('read')) {
        this.get('onsite').setNotificationsRead([notification]);
      }

      let layout = this.get('layout');
      if (layout.get('isTheatreMode') && canTransition) {
        layout.setTheatreMode(false);
      }
    },

    // used by the `center-window` for the primary CTA
    dismissNotification(notification) {
      this.get('onsite').dismissNotification(notification);
      this.trackNotificationInteraction('dismiss', 'center', notification);

      // Load more notifications if a notification is dismissed and there are less than DISMISS_THRESHOLD.
      // The infinite-scroll-slug component only triggers on scroll events. It does not anticipate the parent
      // container shrinking.
      let length = this.get('notifications').length;
      if (length < DISMISS_THRESHOLD) {
        this.get('onsite').loadMoreNotifications();
      }
    }
  }
});
