import {
  SelectorListContent,
  SelectorListContentProps,
  SelectorListItem,
} from '@wix/design-system';
import React, { useEffect, useMemo } from 'react';
import { addEventListener, FiltersMap, KeyedItem } from '@wix/bex-core';
import { observer } from 'mobx-react-lite';
import { PickerContentState } from '../../state';

export type KeyedItemSelectorListItem<T> = SelectorListItem & {
  keyedItem: KeyedItem<T>;
};

export interface PickerSelectorListContentProps<T, F extends FiltersMap>
  extends Partial<SelectorListContentProps> {
  state: PickerContentState<T, F>;
  renderItem?: (item: T, index: number) => Partial<SelectorListItem>;
  hasAdditionalStep?: (props: { item: T }) => boolean;
  spacing?: 30 | 94;
}

function _PickerSelectorListContent<T, F extends FiltersMap>(
  props: PickerSelectorListContentProps<T, F>,
) {
  const {
    state,
    renderItem,
    multiple,
    spacing = 30,
    hasAdditionalStep,
    ...rest
  } = props;

  const { picker } = state;
  const { collection } = picker;
  const {
    bulkSelect,
    result: { keyedItems },
    fetchedLastPage,
  } = collection;

  const { checkedSet, indeterminateSet } = bulkSelect;

  useEffect(() => {
    const disposers = [
      addEventListener(
        bulkSelect.select._map.events,
        'isDisabled',
        (selectionEntry) => {
          const collectionItem = bulkSelect.getCollectionItem(
            selectionEntry.value.key,
          );

          if (!collectionItem) {
            return false;
          }

          const { item, index } = collectionItem;
          return renderItem?.(item, index).disabled || false;
        },
      ),
    ];

    return () => {
      disposers.forEach((d) => d());
    };
  }, [renderItem]);

  const items: KeyedItemSelectorListItem<T>[] = useMemo(
    () =>
      keyedItems.map((keyedItem, index) => ({
        id: keyedItem.key,
        title: collection.itemName(keyedItem.item),
        ...renderItem?.(keyedItem.item, index),
        keyedItem,
      })),
    [keyedItems, renderItem],
  );

  return (
    <SelectorListContent
      items={items}
      infiniteScrollRef={(infiniteScroll) => {
        collection.scrollableContent =
          infiniteScroll?.scrollComponent?.parentElement;
      }}
      searchValue=""
      loadMore={collection.fetchNextPageIfNeeded}
      checkIsSelected={(item) => {
        const { keyedItem } = item as KeyedItemSelectorListItem<T>;
        return checkedSet.has(keyedItem.key);
      }}
      checkIndeterminate={(item) => {
        const { keyedItem } = item as KeyedItemSelectorListItem<T>;
        return indeterminateSet.has(keyedItem.key);
      }}
      onToggle={(item) => {
        const { keyedItem } = item as KeyedItemSelectorListItem<T>;
        picker.toggle(keyedItem, {
          clear: !multiple,
          hasAdditionalStep:
            !multiple && hasAdditionalStep?.({ item: keyedItem.item }),
        });
      }}
      hasMore={!fetchedLastPage}
      multiple={multiple}
      {...rest}
    />
  );
}

export const PickerSelectorListContent = observer(_PickerSelectorListContent);
