import { CANCELLED_STATUS } from 'discourse/lib/autocomplete';
import getUrl from 'discourse-common/lib/get-url';
import discourseDebounce from "discourse/lib/debounce";

var cache = {},
    cacheTopicId,
    cacheTime,
    currentTerm,
    oldSearch;

function performSearch(term, topicId, includeGroups, includeMentionableGroups, includeMessageableGroups, allowedUsers, group, resultsFn) {
  var cached = cache[term];
  if (cached) {
    resultsFn(cached);
    return;
  }

  // need to be able to cancel this
  oldSearch = $.ajax(getUrl('/u/search/users'), {
    data: { term: term,
            topic_id: topicId,
            include_groups: includeGroups,
            include_mentionable_groups: includeMentionableGroups,
            include_messageable_groups: includeMessageableGroups,
            group: group,
            topic_allowed_users: allowedUsers }
  });

  var returnVal = CANCELLED_STATUS;

  oldSearch.then(function (r) {
    cache[term] = r;
    cacheTime = new Date();
    // If there is a newer search term, return null
    if (term === currentTerm) { returnVal = r; }

  }).always(function(){
    oldSearch = null;
    resultsFn(returnVal);
  });
}

var debouncedSearch = discourseDebounce(performSearch, 300);

function organizeResults(r, options) {
  if (r === CANCELLED_STATUS) { return r; }

  var exclude = options.exclude || [],
      limit = options.limit || 5,
      users = [],
      emails = [],
      groups = [],
      results = [];

  if (r.users) {
    r.users.every(function(u) {
      if (exclude.indexOf(u.username) === -1) {
        users.push(u);
        results.push(u);
      }
      return results.length <= limit;
    });
  }

  if (options.term.match(/@/)) {
    let e = { username: options.term };
    emails = [ e ];
    results.push(e);
  }

  if (r.groups) {
    r.groups.every(function(g) {
      if (results.length > limit && options.term.toLowerCase() !== g.name.toLowerCase()) return false;
      if (exclude.indexOf(g.name) === -1) {
        groups.push(g);
        results.push(g);
      }
      return true;
    });
  }

  results.users = users;
  results.emails = emails;
  results.groups = groups;
  return results;
}


export default function userSearch(options) {
  var term = options.term || "",
      includeGroups = options.includeGroups,
      includeMentionableGroups = options.includeMentionableGroups,
      includeMessageableGroups = options.includeMessageableGroups,
      allowedUsers = options.allowedUsers,
      topicId = options.topicId,
      group = options.group;


  if (oldSearch) {
    oldSearch.abort();
    oldSearch = null;
  }

  currentTerm = term;

  return new Ember.RSVP.Promise(function(resolve) {
    // TODO site setting for allowed regex in username
    if (term.match(/[^\w_\-\.@\+]/)) {
      resolve([]);
      return;
    }
    if (((new Date() - cacheTime) > 30000) || (cacheTopicId !== topicId)) {
      cache = {};
    }

    cacheTopicId = topicId;

    var clearPromise = setTimeout(function(){
      resolve(CANCELLED_STATUS);
    }, 5000);

    debouncedSearch(term,
        topicId,
        includeGroups,
        includeMentionableGroups,
        includeMessageableGroups,
        allowedUsers,
        group,
        function(r) {
          clearTimeout(clearPromise);
          resolve(organizeResults(r, options));
        });

  });
}