import { useCombobox } from "downshift";
import * as React from "react";

export interface ComboboxParts {
  input: string;
  popover: string;
  list: string;
  option: string;
}

export interface ComboboxProps {
  items: string[];
  placeholder: string;
  onChange: (value?: string | null) => void;
  parts: ComboboxParts;
  openOnFocus?: boolean;
  selectOnClick?: boolean;
  autocomplete?: boolean;
  persistSelection?: boolean;
}

export const Combobox = ({
  items,
  placeholder,
  onChange,
  openOnFocus,
  selectOnClick,
  autocomplete,
  persistSelection,
  parts,
  ...props
}: ComboboxProps) => {
  const [filteredItems, setFilteredItems] = React.useState(items);
  const {
    isOpen,
    getToggleButtonProps,
    getLabelProps,
    getMenuProps,
    getInputProps,
    highlightedIndex,
    getItemProps,
    selectedItem,
  } = useCombobox({
    onInputValueChange({ inputValue }) {
      setFilteredItems(
        items.filter(
          (value) =>
            inputValue &&
            value?.toLowerCase()?.includes(inputValue.toLowerCase()),
        ),
      );
    },
    onSelectedItemChange({ selectedItem }) {
      onChange(selectedItem);
    },
    items,
    itemToString(item) {
      return item ?? "";
    },
  });

  return (
    <div {...props}>
      <input placeholder={placeholder} {...getInputProps()} />
      <button
        aria-label="toggle menu"
        type="button"
        {...getToggleButtonProps()}
      >
        {isOpen ? <>&#8593;</> : <>&#8595;</>}
      </button>
      <ul {...getMenuProps()}>
        {isOpen && filteredItems.length > 0 ? (
          filteredItems.map((item, index) => (
            <li key={item} {...getItemProps({ item, index })}>
              {item}
            </li>
          ))
        ) : (
          <li>No results</li>
        )}
      </ul>
    </div>
  );
};
