import { multiselect, type MultiSelectSlots, type SlotsToClasses } from '@trail-ui/theme';
import React, {
  useState,
  useRef,
  useEffect,
  forwardRef,
  type ForwardedRef,
  type KeyboardEvent,
  type ChangeEvent,
  type RefObject,
  useMemo,
  ReactNode,
  useId,
} from 'react';
import { CheckIcon, ChevronDownIcon, ErrorIcon } from '@trail-ui/icons';
import Overlay, { popoverDimensions, Positions } from '../overlay/overlay';
import { Input, Label } from '../multiselect/tw-field';
import { Text } from '../multiselect/tw-text';
import { Button } from 'react-aria-components';
import { clsx } from '@trail-ui/shared-utils';

// Types for handling both string and object options
export type BaseOption = {
  label: string;
  value: string | number;
  [key: string]: any;
};

// Constants
const Keys = {
  Backspace: 'Backspace',
  Clear: 'Clear',
  Down: 'ArrowDown',
  End: 'End',
  Enter: 'Enter',
  Escape: 'Escape',
  Home: 'Home',
  Left: 'ArrowLeft',
  PageDown: 'PageDown',
  PageUp: 'PageUp',
  Right: 'ArrowRight',
  Space: ' ',
  Tab: 'Tab',
  Up: 'ArrowUp',
} as const;

// Define specific action types
const MenuActions = {
  Close: 'Close',
  CloseSelect: 'CloseSelect',
  First: 'First',
  Last: 'Last',
  Next: 'Next',
  Open: 'Open',
  Previous: 'Previous',
  Select: 'Select',
  Space: 'Space',
  Type: 'Type',
} as const;

// Types
type MenuActionType = (typeof MenuActions)[keyof typeof MenuActions];
type NavigationAction =
  | typeof MenuActions.First
  | typeof MenuActions.Last
  | typeof MenuActions.Next
  | typeof MenuActions.Previous;

export interface CustomSelectProps {
  /**
   * @property {BaseOption[]} options - The list of options available for selection.
   */
  options: BaseOption[];
  /**
   * @property {string} [value] - The controlled value of the component
   */
  value: BaseOption['values'];
  /**
   * @property {string} [label] - An optional label for the Select component.
   * @default 'Select items'
   */
  label?: string;
  /**
   * @property {string} [id] - An optional id for the Select component.
   */
  id?: string;
  /**
   * @property {string} [labelKey] - The key to use for the label of each option.
   */
  labelKey?: string;
  /**
   * @property {string} [valueKey] - The key to use for the value of each option.
   */
  valueKey?: string;
  /**
   * @param onChange  - A callback function that is called when the selected items change.
   * @returns
   */
  onChange: (selectedItems: string | number) => void;
  /**
   * @param onInputChange  - A callback function that is called when the value of input changes.
   * @returns
   */
  onInputChange?: (e: React.ChangeEvent<HTMLInputElement>) => void /**
   * @property {() => void} [onTriggerBlur] - A callback function that is called when the Select component loses focus.
   */;
  onTriggerBlur?: React.FocusEventHandler<Element>;
  /**
   * @property {() => void} [onBlur] - A callback function that is called when the button or input element loses focus.
   */
  onBlur?: React.FocusEventHandler<Element>;
  /**
   * @property {(e : React.KeyboardEvent) => void} [onKeyDown] - A callback function that is called when any key is pressed in the Select component.
   */
  onKeyDown?: (e: React.KeyboardEvent, isDropdownOpen?: boolean) => void;
  /**
   * @property {SlotsToClasses<MultiSelectSlots>} [classNames] - An optional object of classes to style the Select component.
   */
  classNames?: SlotsToClasses<MultiSelectSlots>;
  /**
   * @property {string} [errorMessage] - An optional error message to display below the Select component.
   */
  errorMessage?: string;
  /**
   * @property {string} [description] - An optional description to display below the Select component.
   */
  description?: string;
  /**
   * @property {string} [placeholder] - An optional placeholder to display in the input field.
   */
  placeholder?: string;
  /**
   * @property {React.ReactNode} [errorIcon] - An optional icon to display next to the error message.
   */
  errorIcon?: React.ReactNode;
  /**
   * @property {string} [errorId] - The id of the error message for accessibility.
   */
  errorId?: string;
  /**
   * @property {boolean} [isRequired] - Whether the Select component is required.
   */
  isRequired?: boolean;
  /**
   * @property {boolean} [isDisabled] - Whether the Select component is disabled.
   */
  isDisabled?: boolean;
  /**
   * @property {boolean} [isInvalid] - Whether the Select component is invalid.
   */
  isInvalid?: boolean;
  /**
   * @property {string} [name] - The name of the form field
   */
  name?: string;
  /**
   * @property {string} [form] - The id of the form this field belongs to
   */
  form?: string;
  /**
   * @property {number} [maxOptionsBeforeConversionToComboBox] - the component will behave as select component if the options.length is less than this value and as a combox once the value exceeds this number
   * note - the isCombox property overrides the behaviour of this feild
   * @default 6
   */
  maxOptionsBeforeConversionToComboBox?: number;
  /**
   * @property {boolean} [isCombobox] - if set to true the components behaves as a combobox, if set to false it will behave as a listbox, if no value is passed it will act as a select if the options.length is less than maxOptionsBeforeConversionToComboBox and as a comboxbox after that
   * @default undefined
   */
  isCombobox?: boolean;
  /**
   * @property {keyof typeof Positions} [position] - the position of the popover with respect to the base element
   * @default Positions.bottom
   */
  position?: keyof typeof Positions;
  /**
   * @property {popoverDimensions} [popover] - the maxHeight and maxWidth of the popover
   */
  popover?: popoverDimensions;
  /**
   * @property {boolean} [isLoading] - the loading state of options
   */
  isLoading?: boolean;
  /**
   * @property {boolean} [allowCustomInput] - allows user to select options not present in the dropdown
   */
  allowCustomInput?: boolean;
  /**
   * @property {boolean} [renderCustomLabel] - allows user to render custom labels in dropdowns
   */
  renderCustomLabel?: (option: BaseOption) => ReactNode;
  /**
   * @property {string} [ariaLabelledBy] - link the control to an element via aria-labelledBy attribute, given priority over label association
   */
  ariaLabelledBy?: string;
  /**
   * @property {RefObject<HTMLDivElement>} [baseRef] - reference of the base element of CustomSelect
   */
  baseRef?: RefObject<HTMLDivElement>;
  /**
   * @property {boolean} [allowDeselection] - allows de selection of option, default value is true
   */
  allowDeselection?: boolean;
}

function getActionFromKey(key: string, menuOpen: boolean): MenuActionType | undefined {
  if (!menuOpen && key === Keys.Down) return MenuActions.Open;
  if (!menuOpen && key === Keys.Enter) return MenuActions.Open;
  if (key === Keys.Down) return MenuActions.Next;
  if (key === Keys.Up) return MenuActions.Previous;
  if (key === Keys.Home) return MenuActions.First;
  if (key === Keys.End) return MenuActions.Last;
  if (key === Keys.Escape) return MenuActions.Close;
  if (key === Keys.Enter) return MenuActions.CloseSelect;
  if (key === Keys.Backspace || key === Keys.Clear || key.length === 1) return MenuActions.Type;
  return undefined;
}

const CustomSelect = forwardRef(
  (
    {
      options,
      label,
      labelKey,
      valueKey,
      id: userProvidedId,
      onChange,
      onTriggerBlur,
      onBlur,
      classNames,
      errorMessage,
      description,
      errorIcon = (
        <ErrorIcon
          className="h-4 w-4 text-red-800 dark:text-red-600"
          role="img"
          aria-label="Error"
          aria-hidden={false}
        />
      ),
      errorId: eID,
      isRequired,
      isDisabled,
      isInvalid,
      placeholder = 'Select items',
      value: selectedValue,
      form,
      name,
      maxOptionsBeforeConversionToComboBox = 6,
      isCombobox,
      position = Positions.bottom,
      popover = { maxHeight: 240 },
      onKeyDown,
      onInputChange,
      isLoading = false,
      allowCustomInput = false,
      renderCustomLabel,
      ariaLabelledBy,
      baseRef,
      allowDeselection = true,
      ...otherprops
    }: CustomSelectProps,
    ref: ForwardedRef<HTMLInputElement | HTMLButtonElement | null>,
  ) => {
    // State
    const [isOpen, setIsOpen] = useState(false);
    const [searchValue, setSearchValue] = useState('');
    const [activeIndex, setActiveIndex] = useState(-1);
    const [value, setValue] = useState<BaseOption>({ label: '', value: '' });

    // Refs
    const listboxRef = useRef<HTMLUListElement>(null);
    const inputRef = useRef<HTMLInputElement>(null);
    const localRef = useRef<HTMLDivElement>(null);
    const buttonRef = useRef<HTMLButtonElement>(null);
    const optionRefs = useRef<Array<RefObject<HTMLLIElement>>>([]);
    const noSearchResultsRef = useRef<HTMLLIElement>(null);
    const hiddenInputRef = useRef<HTMLInputElement>(null);
    const refElementForOverlay = useRef<HTMLDivElement>(null);

    const uuid = useId();
    const uuid2 = useId();

    const id = userProvidedId ?? uuid;
    const errorId = eID || uuid2;

    // Styles
    const slots = useMemo(() => multiselect(), []);
    const isComponentCombobox = useMemo(() => {
      if (isCombobox !== undefined) {
        return isCombobox;
      } else {
        return options.length > maxOptionsBeforeConversionToComboBox;
      }
    }, [isCombobox, options, maxOptionsBeforeConversionToComboBox]);

    const labelId = `${id}-select-label`;
    const optionBoxId = `${id}-select-${isComponentCombobox ? 'combobox' : 'listbox'}`;

    // Helpers
    function getOptionLabel(option: BaseOption, isView: true): ReactNode | string;
    function getOptionLabel(option: BaseOption, isView: false): string;
    function getOptionLabel(option: BaseOption, isView: boolean) {
      if (isView && renderCustomLabel && option.value) {
        return renderCustomLabel?.(option);
      }
      return option?.[labelKey ?? 'label'] || '';
    }

    const getOptionValue = (option: BaseOption): string => {
      return option?.[valueKey ?? 'value'] || '';
    };

    const resetIndex = () => setActiveIndex(-1);

    // Filter options based on search input
    const filteredOptions = useMemo(() => {
      const optList = [];

      if (allowCustomInput) {
        if (
          searchValue &&
          options.findIndex(
            (o) => getOptionLabel(o, false).toLowerCase() === searchValue.toLowerCase(),
          ) === -1
        ) {
          optList.push({ label: searchValue, value: searchValue, isItalic: true } as BaseOption);
        } else if (selectedValue && options.findIndex((o) => o.value === selectedValue) === -1) {
          optList.push({ label: selectedValue, value: selectedValue, isItalic: true });
        }
      }

      return [
        ...optList,
        ...options.filter((option) => {
          return getOptionLabel(option, false)
            .toString()
            .toLowerCase()
            .includes(searchValue.toLowerCase());
        }),
      ];
    }, [searchValue, options, selectedValue]);

    const activedescendant = isOpen
      ? filteredOptions.length > 0 && activeIndex >= 0
        ? `${id}-option-${activeIndex}`
        : `${id}-option-no-data`
      : '';

    const toggleDropdown = () => setIsOpen((prevState) => !prevState);

    const toggleItem = (option: BaseOption) => {
      if (isDisabled) return;

      let newOption = option;
      if (option.value === selectedValue && allowDeselection) {
        newOption = { label: '', value: '' };
      }

      onChange(newOption.value);
      setSearchValue('');
      toggleDropdown();

      if (inputRef.current) {
        inputRef.current.focus();
        inputRef.current.value = getOptionLabel(newOption, false);
      }

      if (buttonRef.current) {
        buttonRef.current.focus();
      }

      // Update hidden input
      if (hiddenInputRef.current) {
        hiddenInputRef.current.value = getOptionLabel(newOption, false);
      }
    };

    // Event handlers
    const handleInputChange = (e: ChangeEvent<HTMLInputElement>) => {
      if (isDisabled) return;
      setSearchValue(e.target.value);
      if (!isOpen) toggleDropdown();
      if (activeIndex === -1) {
        setActiveIndex(0);
      }
    };

    function getUpdatedIndex(current: number, action: NavigationAction): number {
      switch (action) {
        case MenuActions.First:
          return 0;
        case MenuActions.Last:
          return filteredOptions.length;
        case MenuActions.Previous:
          return (activeIndex - 1 + filteredOptions.length) % filteredOptions.length;
        case MenuActions.Next:
          return (activeIndex + 1) % filteredOptions.length;
        default:
          return current;
      }
    }

    const handleKeyDown = (
      e: KeyboardEvent<HTMLLIElement | HTMLInputElement | HTMLOrSVGElement>,
    ) => {
      const action = getActionFromKey(e.key, isOpen);

      if (isDisabled) {
        e.preventDefault();
        return;
      }

      if (e.key === Keys.Tab) {
        if (isOpen) {
          toggleDropdown();
          resetIndex();
          setSearchValue('');
        }
        return;
      }

      if (!action) return;

      if (MenuActions.Type !== action) e.preventDefault();

      switch (action) {
        case MenuActions.Next:
        case MenuActions.Last:
        case MenuActions.First:
        case MenuActions.Previous:
          const nextIndex = getUpdatedIndex(activeIndex, action);
          setActiveIndex(nextIndex);
          noSearchResultsRef.current?.focus();
          break;
        case MenuActions.Type:
          if (inputRef.current) inputRef.current.focus();
          break;
        case MenuActions.CloseSelect:
          if (activeIndex >= 0) {
            optionRefs.current[activeIndex].current?.click();
          }
          break;
        case MenuActions.Close:
          setSearchValue('');
          setIsOpen(false);
          resetIndex();
          break;
        case MenuActions.Open:
          handleOnClick({ detail: 1 } as React.MouseEvent);
          break;
      }
    };

    const handleOnClick = (e?: React.MouseEvent) => {
      //Whenever enter button is clicked on a button element, the onKeyPress and onClick event both are fired
      //This causes a problem that toggleDropdown() is called twice, so the dropdown is closed as soon as it opens
      //The on click event has a property e.detail, if e.detail === 1, it means that the event was triggered due to a onClick and not enter button click
      //Therefore a check is added here, when user clicks enter, in onClck evnet details is 0, so this toggleDropdown is not called, but in onKeyPressEvent when handleOnClick is called inside handleKeyDown we are explicitely passing e.detail as 1, to open the dropdown.
      //In this way on enter click the toggleDropdown is called only once
      if (!isDisabled && e?.detail === 1) {
        toggleDropdown();
        if (isOpen) {
          resetIndex();
        }
      }
    };

    function mergeRefs<T>(...refs: Array<React.Ref<T | null> | undefined>) {
      return (value: T | null) => {
        for (const ref of refs) {
          if (!ref) continue;

          if (typeof ref === 'function') {
            ref(value);
          } else {
            // @ts-ignore – React allows assigning to .current
            ref.current = value;
          }
        }
      };
    }

    function onComponentBlur(e: React.FocusEvent) {
      const selectedOption = filteredOptions.find((o) => o.value === selectedValue);

      if (e.relatedTarget && !localRef.current?.contains(e.relatedTarget)) {
        if (selectedOption) {
          if (inputRef.current) {
            inputRef.current.value = getOptionLabel(selectedOption, false);
          }
          if (hiddenInputRef.current) {
            hiddenInputRef.current.value = getOptionLabel(selectedOption, false);
          }
        }
        onBlur?.(e);
      }
    }

    function announceToScreenReader(message: string) {
      const announcer = document.createElement('div');

      announcer.setAttribute('role', 'alert');
      announcer.setAttribute('aria-live', 'polite');
      // announcer.setAttribute('aria-atomic', 'true');

      // Visually hidden but accessible to screen readers
      announcer.classList.add('sr-only');

      document.body.appendChild(announcer);

      // Small delay ensures screen readers detect the DOM insertion
      setTimeout(() => {
        announcer.textContent = message;
      }, 100);

      // Clean up after announcement
      setTimeout(() => {
        document.body.removeChild(announcer);
      }, 1000);
    }

    // Click outside handler
    useEffect(() => {
      const handleClickOutside = (event: MouseEvent) => {
        if (localRef.current && !localRef.current.contains(event.target as Node)) {
          setIsOpen(false);
        }
      };

      document.addEventListener('mousedown', handleClickOutside, true);
      return () => document.removeEventListener('mousedown', handleClickOutside, true);
    }, []);

    useEffect(() => {
      const index = options.findIndex((item) => item.value === selectedValue);
      const newValue =
        index === -1
          ? allowCustomInput
            ? { label: selectedValue, value: selectedValue, isItalic: true }
            : { label: '', value: '' }
          : options[index];
      setValue(newValue);

      if (inputRef.current) {
        inputRef.current.value = getOptionLabel(newValue, false);
      }
      if (hiddenInputRef.current) {
        hiddenInputRef.current.value = getOptionLabel(newValue, false);
      }
    }, [selectedValue, options]);

    useEffect(() => {
      if (isOpen) {
        optionRefs.current = filteredOptions.map(
          (_, i) => optionRefs.current[i] || React.createRef<HTMLLIElement>(),
        );
        if (filteredOptions.length > 1 && !isCombobox) {
          setActiveIndex(0);
        }

        if (!isLoading) announceToScreenReader(`${filteredOptions.length} results found`);
      }
      buttonRef.current?.setAttribute('role', 'combobox');
    }, [isOpen, filteredOptions]);

    // // Reset active index when filtered options change
    useEffect(() => {
      if (filteredOptions.length > 0) {
        resetIndex();
      }
      if (isRequired) {
        buttonRef.current?.setAttribute('aria-required', String(isRequired));
      }
    }, [filteredOptions]);

    useEffect(() => {
      if (isOpen && activeIndex >= 0) {
        requestAnimationFrame(() => {
          optionRefs.current[activeIndex]?.current?.scrollIntoView({ block: 'nearest' });
        });
      }

      buttonRef.current?.setAttribute(
        'aria-activedescendant',
        isOpen ? `${id}-option-${activeIndex}` : '',
      );
    }, [activeIndex]);

    useEffect(() => {
      buttonRef.current?.setAttribute('data-invalid', `${isInvalid}`);
    }, [isInvalid, options]);

    return (
      <div
        ref={mergeRefs(localRef, baseRef)}
        className={slots.base({ class: classNames?.base })}
        onBlur={onComponentBlur}
      >
        <Label
          id={labelId}
          isDisabled={isDisabled}
          requiredHint={isRequired}
          className={slots.label({ class: classNames?.label })}
        >
          {label}
        </Label>

        <input
          ref={hiddenInputRef}
          type="hidden"
          name={name}
          value={getOptionValue(value)}
          form={form}
          required={isRequired}
        />

        <div
          ref={refElementForOverlay}
          className={slots.inputWrapper({ className: classNames?.inputWrapper })}
        >
          {isComponentCombobox ? (
            <Input
              id={id}
              ref={mergeRefs(inputRef, ref)}
              autoComplete="off"
              aria-busy={isLoading}
              aria-autocomplete="list"
              aria-labelledby={ariaLabelledBy ?? labelId}
              onBlur={onTriggerBlur}
              className={slots.input({ class: classNames?.input })}
              onChange={(e) => {
                handleInputChange(e);
                onInputChange?.(e);
              }}
              onKeyDown={(e) => {
                handleKeyDown(e);
                onKeyDown?.(e, isOpen);
              }}
              onClick={handleOnClick}
              placeholder={!getOptionValue(value) ? placeholder : ''}
              aria-expanded={isOpen}
              aria-controls={optionBoxId}
              aria-activedescendant={activedescendant}
              disabled={isDisabled}
              aria-invalid={isInvalid}
              aria-required={isRequired}
              role="combobox"
              aria-describedby={errorId || ''}
              aria-haspopup="listbox"
              {...otherprops}
            />
          ) : (
            <Button
              id={id}
              ref={mergeRefs(buttonRef, ref)}
              onKeyDown={(e) => {
                handleKeyDown(e);
                onKeyDown?.(e, isOpen);
                e.continuePropagation();
              }}
              onClick={handleOnClick}
              onBlur={onTriggerBlur}
              className={clsx(
                slots.input({ class: classNames?.input }),
                'text-left',
                value.value ? 'text-neutral-900' : 'text-neutral-600',
              )}
              aria-expanded={isOpen}
              aria-controls={optionBoxId}
              aria-activedescendant={activedescendant}
              aria-invalid={isInvalid}
              aria-required={isRequired}
              aria-describedby={errorId || ''}
              aria-labelledby={ariaLabelledBy ?? labelId}
              isDisabled={isDisabled}
              aria-haspopup="listbox"
              {...otherprops}
            >
              {getOptionLabel(value, true) || placeholder}
            </Button>
          )}
          <ChevronDownIcon
            height={24}
            width={24}
            onKeyDown={handleKeyDown}
            onClick={(e) => {
              handleOnClick(e);
              if (isComponentCombobox) inputRef.current?.focus();
              else buttonRef.current?.focus();
            }}
            className={`${isOpen ? 'rotate-180' : ''} cursor-pointer`}
          />
        </div>

        {errorMessage ? (
          <Text
            id={errorId}
            slot="errorMessage"
            aria-live="polite"
            elementType="div"
            className={slots.errorMessage({
              class: classNames?.errorMessage,
            })}
          >
            {errorIcon}
            <span>{errorMessage}</span>
          </Text>
        ) : description ? (
          <Text
            slot="description"
            elementType="div"
            className={slots.description({ class: classNames?.description })}
          >
            <span>{description}</span>
          </Text>
        ) : null}

        <Overlay
          referenceElement={refElementForOverlay}
          position={position}
          style={popover}
          offset={{ x: 8, y: 8 }}
          isOpen={isOpen}
        >
          <ul
            ref={listboxRef}
            role="listbox"
            id={optionBoxId}
            aria-labelledby={ariaLabelledBy ?? labelId}
            aria-busy={isLoading}
            className={clsx(
              slots.popover({ className: classNames?.popover }),
              { hidden: !isOpen },
              'rounded-md border-[1px] bg-neutral-50 shadow-md',
            )}
          >
            {isLoading ? (
              <li
                id={`${id}-option-loading`}
                className={clsx(
                  slots.listboxItem({
                    className: classNames?.listboxItem,
                  }),
                )}
              >
                <span
                  className={slots.listBoxItemLabel({
                    className: classNames?.listBoxItemLabel,
                  })}
                >
                  Loading ...
                </span>
              </li>
            ) : filteredOptions.length > 0 ? (
              filteredOptions.map((option, index) => {
                const isActive = index === activeIndex;

                return (
                  <li
                    key={getOptionValue(option)}
                    ref={optionRefs.current[index]}
                    role="option"
                    id={`${id}-option-${index}`}
                    aria-selected={getOptionValue(value) === getOptionValue(option)}
                    tabIndex={isActive ? 0 : -1}
                    className={clsx(
                      slots.listboxItem({
                        className: classNames?.listboxItem,
                      }),
                      option?.isItalic ? 'italic' : '',
                      `${isActive ? 'border-purple-600 bg-purple-50' : 'border-transparent'} ${getOptionValue(value) === getOptionValue(option) ? 'font-medium' : ''}`,
                    )}
                    onClick={() => toggleItem(option)}
                    onKeyDown={handleKeyDown}
                    onMouseEnter={() => {
                      setActiveIndex(index);
                      optionRefs.current[index].current?.focus();
                    }}
                  >
                    <span
                      className={slots.listBoxItemLabel({
                        className: classNames?.listBoxItemLabel,
                      })}
                    >
                      {getOptionLabel(option, true)}
                    </span>
                    {getOptionValue(value) === getOptionValue(option) && (
                      <span className="flex items-center pl-1.5">
                        <CheckIcon className="h-5 w-5 text-purple-600" />
                      </span>
                    )}
                  </li>
                );
              })
            ) : filteredOptions.length === 0 && options.length === 0 ? (
              <li
                id={`${id}-option-no-data`}
                className={clsx(
                  slots.listboxItem({
                    className: classNames?.listboxItem,
                  }),
                )}
              >
                <span
                  className={slots.listBoxItemLabel({
                    className: classNames?.listBoxItemLabel,
                  })}
                >
                  No Data
                </span>
              </li>
            ) : filteredOptions.length === 0 && options.length !== 0 ? (
              <li
                id={`${id}-option-no-data`}
                ref={noSearchResultsRef}
                className={clsx(
                  slots.listboxItem({
                    className: classNames?.listboxItem,
                  }),
                )}
                // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
                tabIndex={0}
              >
                <span
                  className={slots.listBoxItemLabel({
                    className: classNames?.listBoxItemLabel,
                  })}
                >
                  No Search Results
                </span>
              </li>
            ) : (
              ''
            )}
          </ul>
        </Overlay>
      </div>
    );
  },
);

CustomSelect.displayName = 'CustomSelectComponent';

export default CustomSelect;
