import { UseSelectGetItemPropsOptions } from "downshift";
import React, {
  Dispatch,
  HTMLAttributes,
  MutableRefObject,
  RefObject,
  SetStateAction,
} from "react";
import { List } from "../../List";
import { CreatableOption } from "./CreatableOption";
import { SelectChildrenWithDefaultStatus } from "./SelectChildrenWithDefaultStatus";
import { SelectPortal } from "./SelectPortal";
import { SelectSearch } from "./SelectSearch";
import { SelectOption } from "./types";
import { useSelectLayout } from "../hooks/useSelectLayout";

interface SelectMenuProps<T extends SelectOption>
  extends HTMLAttributes<HTMLDivElement> {
  isOpen: boolean;
  callbackElementProps: ReturnType<
    typeof useSelectLayout
  >["callbackElementProps"];
  menuProps: ReturnType<typeof useSelectLayout>["menuProps"];
  onInputChange: ((newValue: string) => void) | undefined;
  inputRef: RefObject<HTMLInputElement>;
  inputValue: string | undefined;
  setInputHasFocus: Dispatch<SetStateAction<boolean>>;
  popperRef: RefObject<HTMLDivElement>;
  optionIndexRef: MutableRefObject<number>;
  setOptionIndex: (newIndex: number) => void;
  highlightedIndex: number;
  creatableOption: T;
  isCreatable: boolean;
  getItemProps: (options: UseSelectGetItemPropsOptions<T | null>) => any;
  onCreateOption: () => void;
  isLoading: boolean | undefined;
}

export function SelectMenu<T extends SelectOption>({
  isOpen,
  callbackElementProps,
  onInputChange,
  inputRef,
  inputValue,
  setInputHasFocus,
  popperRef,
  optionIndexRef,
  setOptionIndex,
  highlightedIndex,
  creatableOption,
  isCreatable,
  getItemProps,
  onCreateOption,
  isLoading,
  children,
  menuProps,
}: SelectMenuProps<T>) {
  return (
    <SelectPortal>
      <List {...menuProps}>
        {isOpen && (
          <>
            <List.Item {...callbackElementProps} />
            {onInputChange && (
              <SelectSearch
                ref={inputRef}
                value={inputValue}
                onChange={(e) => {
                  onInputChange(e.currentTarget.value);
                }}
                setInputHasFocus={setInputHasFocus}
                popperRef={popperRef}
              />
            )}
            <CreatableOption
              optionIndexRef={optionIndexRef}
              setOptionIndex={setOptionIndex}
              highlightedIndex={highlightedIndex}
              label={creatableOption.label}
              isCreatable={isCreatable}
              onClick={onCreateOption}
              creatableOption={creatableOption}
              getItemProps={getItemProps}
            />
            <SelectChildrenWithDefaultStatus
              isLoading={isLoading}
              inputValue={inputValue}
            >
              {children}
            </SelectChildrenWithDefaultStatus>
          </>
        )}
      </List>
    </SelectPortal>
  );
}
