import { useMemo, useState } from 'react';
import { Meta, Story } from '@storybook/react';
import debounce from 'lodash/debounce';

import { Autocomplete } from './autocomplete';
import type { AutocompleteProps, AutocompleteOptionProps } from './types';
import type { DropDownMenuProps, MenuContentProps } from '../../dropdown-menu';
import type { SearchFieldProps } from '../search-field';
import { getMockUsersDropdownMenuItems } from '../../dropdown-menu';
import { areEqualDropdownMenuItems } from '../../dropdown-menu/helpers';
import { actionIcons } from '../../dropdown-menu/__mocks__/menuItems';

const debounceTime = 1000;
const minInputLength = 3;

const randomDisable = 0; // do not generate disabled users
const mockItems = getMockUsersDropdownMenuItems(5000, randomDisable);

const plusActionIcon = actionIcons[0];
plusActionIcon.handleClick = name => () => {
  alert('Clicked on: ' + name);
};

export default {
  component: Autocomplete,
  title: 'Forms/Autocomplete/Search As You Type',
  argTypes: {}
} as Meta;

const Template: Story<AutocompleteProps> = args => {
  const [searchValue, setSearchValue] = useState('');

  const [autocompleteOptions, setAutocompleteOptions] =
    useState<AutocompleteOptionProps[]>(mockItems);

  const handleSearchChange: SearchFieldProps['handleChangeCallback'] = useMemo(
    () =>
      debounce(e => {
        const newValue = (e?.target ? e.target.value : e) || '';
        if (!newValue || newValue.length >= minInputLength) {
          setSearchValue(newValue);
        }
      }, debounceTime),
    []
  );

  const handleAutocompleteClearClick: AutocompleteProps['handleClear'] = event => {
    event.preventDefault();
    setSearchValue('');
  };

  const handleAutocompleteItemClick: NonNullable<DropDownMenuProps['handleClick']> =
    (name, value) => event => {
      const itemToSelect = { name, value };
      const newItems = autocompleteOptions.map(item => ({
        ...item,
        selected: areEqualDropdownMenuItems(item, itemToSelect)
      }));
      setAutocompleteOptions(newItems);
      alert('Selected: ' + name);
    };

  const modifyMenuItem: MenuContentProps['modifyMenuItem'] = props =>
    props.selected
      ? {
          actionIcons: [],
          showSelectedIcon: true
        }
      : {
          actionIcons: [plusActionIcon]
        };

  return (
    <Autocomplete
      {...args}
      options={autocompleteOptions}
      value={searchValue}
      handleClear={handleAutocompleteClearClick}
      handleMenuClick={handleAutocompleteItemClick}
      handleTextChangeCB={handleSearchChange as AutocompleteProps['handleTextChangeCB']}
      menuContentProps={{
        modifyMenuItem,
        showSelectedIcon: true
      }}
    />
  );
};

export const Primary = Template.bind({});
Primary.args = {
  minInputLength: minInputLength,
  placeholder: 'Start typing to search',
  variableSizeList: true
};
