import { useMemo, useState } from 'react';

import {
  Flex,
  Input,
  InputGroup,
  InputRightElement,
  Spinner,
  Tag,
  TagCloseButton,
  TagLabel,
  Wrap,
  WrapItem,
} from '@chakra-ui/react';
import { MdSearch } from 'react-icons/md';

import {
  FormSelectList,
  SelectMultipleValueDisplayType,
} from '@/components/form/FormSelectList';
import { isNullOrUndefined } from '@/utils/validator';

export type SelectMultipleProps = {
  options?: object[];
  values?: (number | string)[];
  onChange?: (value: (number | string)[] | undefined) => void;
  keyKey?: string;
  keyValue?: string;
};

export const SelectMultiple = ({
  options,
  onChange,
  values,
  keyKey = 'id',
  keyValue = keyKey,
}: SelectMultipleProps) => {
  const [showList, setShowList] = useState(false);
  const transformedOption = useMemo(() => {
    return options?.map((element) => {
      return {
        id: element[keyKey],
        name: element[keyValue],
        isSelected: false,
      } as SelectMultipleValueDisplayType;
    });
  }, [options, keyKey, keyValue]);
  const [currentSearch, setCurrentSearch] = useState<string | undefined>(
    undefined
  );

  const selectedOptions = useMemo(() => {
    if (isNullOrUndefined(values) || !transformedOption) {
      return [];
    }
    return transformedOption.filter((element) => {
      return values.includes(element[keyKey]);
    });
  }, [values, transformedOption]);

  const selectValue = (data: SelectMultipleValueDisplayType) => {
    const newValues = values?.includes(data.id)
      ? values.filter((elem) => data.id === elem)
      : [...(values ?? []), data.id];
    setShowList(false);
    if (onChange) {
      if (newValues.length == 0) {
        onChange(undefined);
      } else {
        onChange(newValues);
      }
    }
  };
  if (!options) {
    return <Spinner />;
  }
  function onChangeInput(value: string): void {
    if (value === '') {
      setCurrentSearch(undefined);
    } else {
      setCurrentSearch(value);
    }
  }

  return (
    <Flex direction="column" width="full" gap="0px">
      {selectedOptions && (
        <Wrap spacing="5px" justify="left" width="full" marginBottom="2px">
          {selectedOptions.map((data) => (
            <WrapItem key={data[keyKey]}>
              <Tag
                size="md"
                key="md"
                borderRadius="5px"
                variant="solid"
                backgroundColor="green.500"
              >
                <TagLabel>{data[keyValue] ?? `id=${data[keyKey]}`}</TagLabel>
                <TagCloseButton onClick={() => selectValue(data)} />
              </Tag>
            </WrapItem>
          ))}
        </Wrap>
      )}
      <InputGroup minWidth="50%" marginLeft="auto">
        <InputRightElement pointerEvents="none">
          <MdSearch color="gray.300" />
        </InputRightElement>
        <Input
          onChange={(e) => onChangeInput(e.target.value)}
          //onSubmit={onSubmit}
          onFocus={() => setShowList(true)}
          onBlur={() => setTimeout(() => setShowList(false), 200)}
        />
      </InputGroup>
      {showList && (
        <FormSelectList
          options={transformedOption}
          selected={selectedOptions}
          search={currentSearch}
          onSelectValue={selectValue}
        />
      )}
    </Flex>
  );
};
