import _ from 'underscore';

/**
 * Makes search request for content when user types a value in the search input.
 * Updates the html content of the page with the received one.
 */

export default class FilterableList {
  constructor(form, filter, holder, filterInputField = 'filter_groups') {
    this.filterForm = form;
    this.listFilterElement = filter;
    this.listHolderElement = holder;
    this.filterInputField = filterInputField;
    this.isBusy = false;
  }

  getFilterEndpoint() {
    return `${this.filterForm.getAttribute('action')}?${$(this.filterForm).serialize()}`;
  }

  getPagePath() {
    return this.getFilterEndpoint();
  }

  initSearch() {
    // Wrap to prevent passing event arguments to .filterResults;
    this.debounceFilter = _.debounce(this.onFilterInput.bind(this), 500);

    this.unbindEvents();
    this.bindEvents();
  }

  onFilterInput() {
    const $form = $(this.filterForm);
    const queryData = {};
    const filterGroupsParam = $form.find(`[name="${this.filterInputField}"]`).val();

    if (filterGroupsParam) {
      queryData[this.filterInputField] = filterGroupsParam;
    }

    this.filterResults(queryData);

    if (this.setDefaultFilterOption) {
      this.setDefaultFilterOption();
    }
  }

  bindEvents() {
    this.listFilterElement.addEventListener('input', this.debounceFilter);
  }

  unbindEvents() {
    this.listFilterElement.removeEventListener('input', this.debounceFilter);
  }

  filterResults(queryData) {
    if (this.isBusy) {
      return false;
    }

    $(this.listHolderElement).fadeTo(250, 0.5);

    return $.ajax({
      url: this.getFilterEndpoint(),
      data: queryData,
      type: 'GET',
      dataType: 'json',
      context: this,
      complete: this.onFilterComplete,
      beforeSend: () => {
        this.isBusy = true;
      },
      success: (response, textStatus, xhr) => {
        this.onFilterSuccess(response, xhr, queryData);
      },
    });
  }

  onFilterSuccess(response, xhr, queryData) {
    if (response.html) {
      this.listHolderElement.innerHTML = response.html;
    }

    // Change url so if user reload a page - search results are saved
    const currentPath = this.getPagePath(queryData);

    return window.history.replaceState({
      page: currentPath,
    }, document.title, currentPath);
  }

  onFilterComplete() {
    this.isBusy = false;
    $(this.listHolderElement).fadeTo(250, 1);
  }
}
