import {
  DropdownCollectionFilterState,
  DropdownCollectionFilterStateParams,
} from '../../state';
import { FiltersMap } from '@wix/bex-core';
import { action, makeObservable, observable } from 'mobx';
import debounce from 'lodash/debounce';

export interface AutoCompleteFilterStateParams<V, F extends FiltersMap>
  extends DropdownCollectionFilterStateParams<V, F> {}

export class AutoCompleteFilterState<V, F extends FiltersMap> {
  dropdown: DropdownCollectionFilterState<V, F>;
  searchInputValue = '';

  constructor(params: AutoCompleteFilterStateParams<V, F>) {
    this.dropdown = new DropdownCollectionFilterState(params);

    makeObservable(this, {
      syncSelectedToInput: action.bound,
      clearSelectionAndSearch: action.bound,
      onInputBlur: action.bound,
      searchInputValue: observable.ref,
    });

    const { events } = this.dropdown.dropdownSelect;
    events.on('syncSelectedItems', this.syncSelectedToInput);

    this.syncSelectedToInput();
  }

  syncSelectedToInput() {
    const {
      dropdown: {
        dropdownSelect,
        collectionFilter: { collection },
      },
    } = this;
    const [selected] = dropdownSelect.selectedItems;

    collection.search('');

    if (selected) {
      this.searchInputValue = collection.itemName(selected);
    } else {
      this.searchInputValue = '';
    }
  }

  clearSelectionAndSearch() {
    const {
      dropdown: { dropdownSelect },
      collection,
    } = this;
    this.searchInputValue = '';
    dropdownSelect.clear();
    collection.clearSearch();
  }

  _scheduleOnInputBlur = debounce(
    action((searchValue: string) => {
      const {
        dropdown: { dropdownSelect },
        searchInputValue,
      } = this;

      if (searchValue !== searchInputValue) {
        return;
      }

      if (!searchInputValue) {
        dropdownSelect.clear();
      } else {
        this.syncSelectedToInput();
      }
    }),
    100,
  );

  onInputBlur() {
    this._scheduleOnInputBlur(this.searchInputValue);
  }

  get collection() {
    const {
      dropdown: {
        collectionFilter: { collection },
      },
    } = this;

    return collection;
  }

  init() {
    return this.dropdown.init();
  }
}
