define([

'jquery'

], function ($) {

function InfiniteScroll (decorated, $element, options, dataAdapter) {
  this.lastParams = {};

  decorated.call(this, $element, options, dataAdapter);

  this.$loadingMore = this.createLoadingMore();
  this.loading = false;
}

InfiniteScroll.prototype.append = function (decorated, data) {
  this.$loadingMore.remove();
  this.loading = false;

  decorated.call(this, data);

  if (this.showLoadingMore(data)) {
    this.$results.append(this.$loadingMore);
  }
};

InfiniteScroll.prototype.bind = function (decorated, container, $container) {
  var self = this;

  decorated.call(this, container, $container);

  container.on('query', function (params) {
    self.lastParams = params;
    self.loading = true;
  });

  container.on('query:append', function (params) {
    self.lastParams = params;
    self.loading = true;
  });

  this.$results.on('scroll', function () {
    var isLoadMoreVisible = $.contains(
      document.documentElement,
      self.$loadingMore[0]
    );

    if (self.loading || !isLoadMoreVisible) {
      return;
    }

    var currentOffset = self.$results.offset().top +
      self.$results.outerHeight(false);
    var loadingMoreOffset = self.$loadingMore.offset().top +
      self.$loadingMore.outerHeight(false);

    if (currentOffset + 50 >= loadingMoreOffset) {
      self.loadMore();
    }
  });
};

InfiniteScroll.prototype.loadMore = function () {
  this.loading = true;

  var params = $.extend({}, {page: 1}, this.lastParams);

  params.page++;

  this.trigger('query:append', params);
};

InfiniteScroll.prototype.showLoadingMore = function (_, data) {
  return data.pagination && data.pagination.more;
};

InfiniteScroll.prototype.createLoadingMore = function () {
  var $option = $(
    '<li ' +
    'class="select2-results__option select2-results__option--load-more"' +
    'role="treeitem" aria-disabled="true"></li>'
  );

  var message = this.options.get('translations').get('loadingMore');

  $option.html(message(this.lastParams));

  return $option;
};

return InfiniteScroll;

});