import { AutoCompleteReadonlyState } from '../components/CollectionViewsDropdown/AutoCompleteReadonlyState';
import { CollectionFilterState } from './CollectionFilterState';
import { DropdownSelectState } from './DropdownSelectState';
import { WixPatternsContainer, FiltersMap } from '@wix/bex-core';
import { action, computed, makeObservable, observable } from 'mobx';
import { FilterToolbarState } from '../providers';

export interface DropdownCollectionFilterStateParams<
  V,
  F extends FiltersMap = FiltersMap,
> {
  collectionFilter: CollectionFilterState<V, F>;
  resetOnClose?: boolean;
  container: WixPatternsContainer;
  toolbar: FilterToolbarState;
}

export class DropdownCollectionFilterState<
  V,
  F extends FiltersMap = FiltersMap,
> {
  readonly container;
  readonly collectionFilter: DropdownCollectionFilterStateParams<
    V,
    F
  >['collectionFilter'];

  readonly dropdownSelect: DropdownSelectState<V>;
  readonly resetOnClose: DropdownCollectionFilterStateParams<
    V,
    F
  >['resetOnClose'];

  inputState;

  promotedItems: string[] = [];

  get shouldShowPlaceholder() {
    return (
      this.inputState.disableEditing ||
      this.collectionFilter.collection.query.search.isEmpty
    );
  }

  get inputValue() {
    return this.shouldShowInputValue
      ? this.collectionFilter.collection.query.search.value
      : '';
  }

  get shouldShowInputValue() {
    return this.dropdownSelect.dropdown.isOn || !this.inputState.disableEditing;
  }

  onOptionsShow() {
    this.promotedItems = this.collectionFilter.select.selectedValues.map(
      (item) => item.key,
    );
    this.dropdownSelect.open();
  }

  constructor(params: DropdownCollectionFilterStateParams<V, F>) {
    this.resetOnClose = params.resetOnClose;
    this.container = params.container;
    this.inputState = new AutoCompleteReadonlyState();

    this.collectionFilter = params.collectionFilter;

    const { collectionFilter } = this;

    const { select, filter } = collectionFilter;

    this.dropdownSelect = new DropdownSelectState<V>({
      select,
      container: params.container,
      toolbar: params.toolbar,
      filter,
    });

    makeObservable(this, {
      init: action.bound,
      shouldShowPlaceholder: computed,
      inputValue: computed,
      shouldShowInputValue: computed,
      promotedItems: observable.ref,
      onOptionsShow: action.bound,
    });
  }

  init({ skipInitialFetch }: { skipInitialFetch?: boolean } = {}) {
    const { dropdownSelect, resetOnClose, collectionFilter } = this;
    const { collection } = collectionFilter;

    const disposers = [
      dropdownSelect.init(),
      collection.init({
        skipInitialFetch,
      }),
    ];

    if (resetOnClose) {
      dropdownSelect.events.on('close', collection.resetFiltersAndRefresh);
    }

    return () => {
      for (const disposer of disposers) {
        disposer();
      }

      if (resetOnClose) {
        dropdownSelect.events.removeListener(
          'close',
          collection.resetFiltersAndRefresh,
        );
      }
    };
  }
}
