import $ from 'jquery';
import _ from 'underscore';
import axios from './lib/utils/axios_utils';

/**
 * 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(params) {
    if (this.isBusy) {
      return false;
    }

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

    this.isBusy = true;

    return axios.get(this.getFilterEndpoint(), {
      params,
    }).then((res) => {
      this.onFilterSuccess(res, params);
      this.onFilterComplete();
    }).catch(() => this.onFilterComplete());
  }

  onFilterSuccess(response, queryData) {
    if (response.data.html) {
      this.listHolderElement.innerHTML = response.data.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);
  }
}
