import { isBlank, isEmpty } from 'ember-utils';
import observer from 'ember-metal/observer';
import run from 'ember-runloop';
import $ from 'jquery';
import Component from 'ember-component';
import computed from 'ember-computed';
import { truncateInteger } from 'web-client/utilities/friends-list/computed';
import { libs, routes } from 'web-client/utilities/friends-list/settings';
import { storageFor } from 'ember-local-storage';
import injectService from 'ember-service/inject';

export default Component.extend({
  classNames: ['friend-list'],
  session: injectService(),
  search: injectService('twitch-friends-list/search'),
  tracking: injectService(),
  friends: injectService('twitch-friends-list/friends'),
  requests: injectService('twitch-friends-list/requests'),
  unseenRequestsCount: truncateInteger('requests.notificationsCount', 20),
  friendsRoute: routes.friends,
  requestsOpenTracked: false,
  onClick: null,
  isFriendsOpen: true,
  settings: storageFor('twitch-friend-settings'),
  onboardingDismissed: computed.alias('settings.onboardingDismissed'),
  isCollapsed: false,

  query: null,
  hasQuery: computed.notEmpty('query'),

  searchResults: null,
  friendResults: null,
  isLoading: false,
  hasError: false,

  errorText: computed("query", function() {
    let translation = libs.i18n("Sorry, we couldn't find anyone named \"{{login}}\"");
    return translation.replace("{{login}}", this.get("query"));
  }),

  hasFriends: computed.notEmpty('friends.friends'),

  shouldDisplayCount: computed('requests.notificationsCount', 'requests.isNotificationsCountLoading', function() {
    // We have to make sure it's done loading otherwise it'll display "NULL"
    return !this.get('requests.isNotificationsCountLoading') &&
            this.get('requests.notificationsCount') > 0;
  }),
  isEmptySearch: computed('hasQuery', 'searchResults.length', 'friendResults.length', 'isLoading', function() {
    return this.get('hasQuery') &&
           !this.get('searchResults.length') &&
           !this.get('friendResults.length') &&
           !this.get('isLoading');
  }),

  showOnboarding: computed('friends.friends.[]', 'onboardingDismissed', 'hasQuery', function () {
    return !this.get('onboardingDismissed') &&
           isEmpty(this.get('friends.friends')) &&
           !this.get('hasQuery');
  }),

  clickEventId: null,

  clickOutsideHandler(event) {
    let $this = this.$();
    let $target = $(event.target);
    if (!$this.is($target) && isBlank($this.has($target))) {
      this._clearSearch();
    }
  },

  _onCollapse: observer('isCollapsed', function () {
    if (this.get('isCollapsed')) {
      this.set('isFriendsOpen', true);
    }
  }),

  didInsertElement() {
    this._super();
    let eventId = `click.outsideSearch.${this.get('elementId')}`;
    this.set('clickEventId', eventId);
    $(window).on(eventId, run.bind(this, this.clickOutsideHandler));
  },

  willDestroyElement() {
    $(window).off(this.get('clickEventId'));
    this._super();
  },

  _search(query) {
    if (this.isDestroyed) { return; }
    this.get('search').search(query).then(results => {
      if (this.isDestroyed) { return; }
      if (this.get('query').trim().toLowerCase() !== query) {
        //
        // If the query changed while we were fetching results, throw
        // away the results.
        //
        return;
      }
      this.set('searchResults', results);
    }, (e) => {
      if (this.isDestroyed) { return; }
      this.set('hasError', true);
      throw e;
    }).finally(() => {
      if (this.isDestroyed) { return; }
      this.set('isLoading', false);
    });
  },

  _clearSearch() {
    this.set('searchResults', null);
    this.set('friendResults', null);
    this.set('query', '');
    this.set('isLoading', false);
    this.set('hasError', false);
  },

  actions: {
    search(query) {
      if (this.get('query') === query) {
        return;
      }

      this.set('isLoading', true);
      this.set('query', query);
      query = query.trim().toLowerCase();

      if (!query) {
        this._clearSearch();
        return;
      }

      let friends = this.get('friends').search(query);
      this.set('friendResults', friends);

      // this._search(query);

      // TODO: before merge. Figure out a good way to do this.
      run.debounce(this, '_search', query, 500);
    },

    openFriends() {
      this.set('isFriendsOpen', true);
    },

    openRequests() {
      if (!this.get('requestsOpenTracked')) {
        this.get('tracking').trackEvent({
          event: 'friend_request_list_view',
          data: {
            time: new Date().toString(),
            login: this.get('session.userData.login'),
            ui_context: 'link'
          }
        });
        this.set('requestsOpenTracked', true);
      }
      this.set('isFriendsOpen', false);
      this._clearSearch();
    },

    dismissOnboarding() {
      this.set('onboardingDismissed', true);
    }
  }
});
