import RestModel from 'discourse/models/rest';
import Model from 'discourse/models/model';


function topicsFrom(result, store) {
  if (!result) { return; }

  // Stitch together our side loaded data
  const categories = Discourse.Category.list(),
        users = Model.extractByKey(result.users, Discourse.User);

  return result.topic_list.topics.map(function (t) {
    t.category = categories.findBy('id', t.category_id);
    t.posters.forEach(function(p) {
      p.user = users[p.user_id];
    });
    if (t.participants) {
      t.participants.forEach(function(p) {
        p.user = users[p.user_id];
      });
    }
    return store.createRecord('topic', t);
  });
}

const TopicList = RestModel.extend({
  canLoadMore: Em.computed.notEmpty("more_topics_url"),

  forEachNew: function(topics, callback) {
    const topicIds = [];
    _.each(this.get('topics'),function(topic) {
      topicIds[topic.get('id')] = true;
    });

    _.each(topics,function(topic) {
      if(!topicIds[topic.id]) {
        callback(topic);
      }
    });
  },

  refreshSort: function(order, ascending) {
    const self = this,
        params = this.get('params') || {};

    params.order = order || params.order;

    if (ascending === undefined) {
      params.ascending = ascending;
    } else {
      params.ascending = ascending;
    }

    this.set('loaded', false);
    const store = this.store;
    store.findFiltered('topicList', {filter: this.get('filter'), params}).then(function(tl) {
      const newTopics = tl.get('topics'),
            topics = self.get('topics');

      topics.clear();
      topics.pushObjects(newTopics);
      self.setProperties({ loaded: true, more_topics_url: tl.get('topic_list.more_topics_url') });
    });
  },

  loadMore: function() {
    if (this.get('loadingMore')) { return Ember.RSVP.resolve(); }

    const moreUrl = this.get('more_topics_url');
    if (moreUrl) {
      const self = this;
      this.set('loadingMore', true);

      const store = this.store;
      return Discourse.ajax({url: moreUrl}).then(function (result) {
        let topicsAdded = 0;

        if (result) {
          // the new topics loaded from the server
          const newTopics = topicsFrom(result, store),
              topics = self.get("topics");

          self.forEachNew(newTopics, function(t) {
            t.set('highlight', topicsAdded++ === 0);
            topics.pushObject(t);
          });

          self.setProperties({
            loadingMore: false,
            more_topics_url: result.topic_list.more_topics_url
          });

          Discourse.Session.currentProp('topicList', self);
          return self.get('more_topics_url');
        }
      });
    } else {
      // Return a promise indicating no more results
      return Ember.RSVP.resolve();
    }
  },


  // loads topics with these ids "before" the current topics
  loadBefore: function(topic_ids){
    const topicList = this,
        topics = this.get('topics');

    // refresh dupes
    topics.removeObjects(topics.filter(function(topic){
      return topic_ids.indexOf(topic.get('id')) >= 0;
    }));

    const url = Discourse.getURL("/") + this.get('filter') + "?topic_ids=" + topic_ids.join(",");

    const store = this.store;
    return Discourse.ajax({ url }).then(function(result) {
      let i = 0;
      topicList.forEachNew(topicsFrom(result, store), function(t) {
        // highlight the first of the new topics so we can get a visual feedback
        t.set('highlight', true);
        topics.insertAt(i,t);
        i++;
      });
      Discourse.Session.currentProp('topicList', topicList);
    });
  }
});

TopicList.reopenClass({

  munge(json, store) {
    json.inserted = json.inserted || [];
    json.can_create_topic = json.topic_list.can_create_topic;
    json.more_topics_url = json.topic_list.more_topics_url;
    json.draft_key = json.topic_list.draft_key;
    json.draft_sequence = json.topic_list.draft_sequence;
    json.draft = json.topic_list.draft;
    json.for_period = json.topic_list.for_period;
    json.loaded = true;
    json.per_page = json.topic_list.per_page;
    json.topics = topicsFrom(json, store);

    if (json.topic_list.filtered_category) {
      json.category = Discourse.Category.create(json.topic_list.filtered_category);
    }
    return json;
  },

  find(filter, params) {
    const store = Discourse.__container__.lookup('store:main');
    return store.findFiltered('topicList', {filter, params});
  },

  list(filter) {
    Ember.warn('`Discourse.TopicList.list` is deprecated. Use the store instead');
    return this.find(filter);
  },

  // Sets `hideCategory` if all topics in the last have a particular category
  hideUniformCategory(list, category) {
    const hideCategory = !list.get('topics').any(function (t) { return t.get('category') !== category; });
    list.set('hideCategory', hideCategory);
  }

});

export default TopicList;
