import { flatMapDeep } from 'lodash';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { BaseMultiSelect } from './containers/base-multi-select';
import { isOptionsGroup } from './guards';
import {
  AutocompleteMultiSelectProps,
  BaseMultiSelectProps,
  BaseOption as BaseOptionType,
  MultiSelectType,
} from './types';
import { AutocompleteMultiSelect } from 'common/components/select/containers/autocomplete-multi-select';

const Root = <T extends BaseOptionType, P extends {} = {}>(
  props: BaseMultiSelectProps<T, P> | AutocompleteMultiSelectProps<T, P>
) => {
  const { type, valueIds, isDisabled, isOpened } = props;

  const [isMenuOpen, setIsMenuOpen] = useState(false);

  const flattenedOptions = useMemo(
    () => flatMapDeep(props.options, option => (isOptionsGroup(option) ? option.options : option)),
    [props.options]
  );

  const value = useMemo(() => flattenedOptions.filter(({ id }) => valueIds.includes(id)) || null, [
    flattenedOptions,
    valueIds,
  ]);

  const openMenu = useCallback(() => {
    if (isDisabled) return;
    setIsMenuOpen(true);
  }, [isDisabled]);

  const closeMenu = useCallback(() => {
    setIsMenuOpen(false);
  }, []);

  useEffect(() => {
    if (isOpened !== undefined) {
      requestAnimationFrame(() => {
        setIsMenuOpen(isOpened);
      });
    }
  }, [isOpened]);

  switch (type) {
    case MultiSelectType.Base:
      return (
        <BaseMultiSelect {...props} value={value} isMenuOpen={isMenuOpen} openMenu={openMenu} closeMenu={closeMenu} />
      );
    case MultiSelectType.AutoComplete:
      return (
        <AutocompleteMultiSelect
          {...props}
          value={value}
          isMenuOpen={isMenuOpen}
          openMenu={openMenu}
          closeMenu={closeMenu}
        />
      );
  }
};

export const MultiSelect = React.memo(Root) as typeof Root;
