import React, { useEffect, useState } from 'react';
import {
  CollectionFilterState,
  DropdownCollectionFilterState,
} from '../../state';
import { observer } from 'mobx-react-lite';
import { CollectionState, FiltersMap } from '@wix/bex-core';
import {
  MultiSelectFilterBase,
  MultiSelectFilterBaseProps,
} from '../MultiSelectFilterBase';
import { ListItem, useBuildOption } from '../../hooks';
import { useWixPatternsContainer } from '@wix/bex-core/react';
import {
  useFilterToolbarState,
  FilterTranslationProvider,
} from '../../providers';
import { useFilterCollectionStates } from '../../hooks/useFilterCollectionStates';
import {
  CollectionFilterInitialFetchTimingProps,
  useCollectionFilterInitialFetchTiming,
} from '../../hooks/useCollectionFilterInitialFetchTiming';

export interface MultiSelectCollectionFilterProps<V, F extends FiltersMap>
  extends Omit<MultiSelectFilterBaseProps<V>, 'options' | 'dropdownSelect'>,
    CollectionFilterInitialFetchTimingProps {
  /**
   * A collection state object to fetch the dropdown items.<br>
   * A collection created using [useFilterCollection](./?path=/story/features-filter-hooks--usefiltercollection) or [useStaticListFilterCollection](./?path=/story/features-filter-hooks--usestaticlistfiltercollection)
   * @external
   */
  collection: CollectionState<V, F>;
  /**
   * A function that returns a [ListItemSelectProps](https://www.docs.wixdesignsystem.com/?path=/story/components-form-dropdownlistitems--listitemselect) (Optional)
   * @external
   */
  renderItem?: (item: V, index: number) => ListItem;
}

function _MultiSelectCollectionFilter<V, F extends FiltersMap>(
  props: MultiSelectCollectionFilterProps<V, F>,
) {
  const { filter, collection, renderItem, initialFetchTiming, ...rest } = props;

  const container = useWixPatternsContainer();
  const toolbar = useFilterToolbarState();

  const buildOption = useBuildOption<V>({
    filter,
    renderItem,
  });

  const [collectionFilter] = useState(
    () =>
      new CollectionFilterState({
        collection,
        filter,
      }),
  );

  const [{ dropdownSelect, init }] = useState(
    () =>
      new DropdownCollectionFilterState({
        collectionFilter,
        resetOnClose: true,
        container,
        toolbar,
      }),
  );

  const {
    query: { search },
  } = collection;

  const { skipInitialFetch, onFocus } =
    useCollectionFilterInitialFetchTiming(props);

  useEffect(() => init({ skipInitialFetch }), []);

  const {
    result: { keyedItems },
    fetchedLastPage,
  } = collection;

  const options = keyedItems.map(buildOption);
  const { fixedFooter, showInitialLoader } = useFilterCollectionStates({
    collection,
    fixedFooter: rest.fixedFooter,
  });

  return (
    <MultiSelectFilterBase
      {...rest}
      fixedFooter={fixedFooter}
      infiniteScroll
      value={search.value}
      onChange={(e) => {
        collection.search(e.target.value, { clearResult: true });
      }}
      onFocus={onFocus}
      filter={filter}
      dropdownSelect={dropdownSelect}
      options={options}
      hasMore={!showInitialLoader && !fetchedLastPage}
      loadMore={collection.fetchNextPageIfNeeded}
    />
  );
}

const MultiSelectCollectionFilterInternal = observer(
  _MultiSelectCollectionFilter,
);

export function MultiSelectCollectionFilter<V, F extends FiltersMap>(
  props: MultiSelectCollectionFilterProps<V, F>,
) {
  return (
    <FilterTranslationProvider>
      <MultiSelectCollectionFilterInternal {...props} />
    </FilterTranslationProvider>
  );
}

MultiSelectCollectionFilter.displayName = 'MultiSelectCollectionFilter';
