import { useCallback, useMemo, useState } from 'react';
import { Story } from '@storybook/react';

import { DropDownMenuProps } from '../../../../dropdown-menu';

import { Autocomplete } from '../../../../@forms/autocomplete';
import type { AutocompleteProps, AutocompleteOptionProps } from '../../../../@forms/autocomplete';

export const AutoCompleteTemplate: Story<AutocompleteProps> = args => {
  const { defaultValue, options } = args;

  const selectedOptions = useMemo(() => {
    if (!defaultValue) return options;
    const defaultValues = (
      Array.isArray(defaultValue) ? defaultValue : [defaultValue]
    ) as AutocompleteOptionProps[];
    return options?.map(option => ({
      ...option,
      selected: !!defaultValues?.find(value => option?.name === value?.name)
    }));
  }, [defaultValue, options]);

  // Autocomplete single
  const [autocompleteOptionsSingle, setAutocompleteOptionsSingle] = useState(selectedOptions);

  const handleAutocompleteItemClickSingle: NonNullable<DropDownMenuProps['handleClick']> =
    v => () => {
      setAutocompleteOptionsSingle(
        autocompleteOptionsSingle.map(o => ({
          ...o,
          selected: v === o.name ? !o.selected : false
        }))
      );
    };

  const autocompleteValueSingle = useMemo(
    () => autocompleteOptionsSingle.find(o => o.selected) || ({} as AutocompleteOptionProps),
    [autocompleteOptionsSingle]
  );

  // Autocomplete multiple
  const [autocompleteOptionsMultiple, setAutocompleteOptionsMultiple] = useState(selectedOptions);

  const handleAutocompleteItemClickMultiple: NonNullable<DropDownMenuProps['handleClick']> =
    v => () => {
      setAutocompleteOptionsMultiple(
        autocompleteOptionsMultiple.map(o => ({
          ...o,
          selected: v === o.name ? !o.selected : o.selected
        }))
      );
    };

  const autocompleteValueMultiple = useMemo(
    () => autocompleteOptionsMultiple.filter(o => o.selected),
    [autocompleteOptionsMultiple]
  );

  const [textMultiple, setTextMultiple] = useState('');

  const displayOptionsMultiple = useMemo(() => {
    if (!textMultiple) {
      return autocompleteOptionsMultiple;
    }

    return autocompleteOptionsMultiple.filter(o =>
      o.name.toString().toLowerCase().includes(textMultiple)
    );
  }, [autocompleteOptionsMultiple, textMultiple]);

  const handleAutocompleteMultipleTextChange: AutocompleteProps['handleTextChangeCB'] = useCallback(
    e => {
      setTextMultiple(e.target.value);
    },
    []
  );

  // Autocomplete freeSolo
  const handleAutocompleteClear: AutocompleteProps['handleClear'] = useCallback(() => {
    setAutocompleteOptionsMultiple(
      autocompleteOptionsMultiple.map(option => ({
        ...option,
        selected: false
      }))
    );
  }, [autocompleteOptionsMultiple]);

  const handleAutocompleteCreate: AutocompleteProps['handleCreate'] = useCallback(
    (e, v) => {
      const value = v.slice(-1)[0]?.toString();
      value &&
        setAutocompleteOptionsMultiple(
          autocompleteOptionsMultiple.concat([
            {
              name: value,
              selected: true
            }
          ])
        );
    },
    [autocompleteOptionsMultiple]
  );

  const handleAutocompleteDelete: AutocompleteProps['handleDelete'] = useCallback((e, v) => {
    setAutocompleteOptionsMultiple(v);
  }, []);

  return (
    <Autocomplete
      handleClear={handleAutocompleteClear}
      handleCreate={handleAutocompleteCreate}
      handleDelete={handleAutocompleteDelete}
      {...args}
      value={args.multiple ? autocompleteValueMultiple : autocompleteValueSingle}
      options={args.multiple ? autocompleteOptionsMultiple : autocompleteOptionsSingle}
      handleMenuClick={
        args.multiple ? handleAutocompleteItemClickMultiple : handleAutocompleteItemClickSingle
      }
      displayOptions={displayOptionsMultiple}
      handleTextChangeCB={handleAutocompleteMultipleTextChange}
    />
  );
};
