import React, {
  useState,
  useEffect,
  useRef,
  useMemo,
  useCallback,
} from "react";
import { Alert } from "../Alert";
import ReactSelect from "react-select";
import Dropdown from "./dropdown";
import { SelectedOptionsTags } from "./selected-option-tags";
import SearchFilter from "./SearchFilter";
import { MenuList } from "./menuList";
import { Option } from "./optionList";
import { Checkbox } from "../Checkbox";
import { Toast } from "../Toast";
import { Tooltip } from "../Tooltip";
import { CustomGroupHeading } from "./customGroupHeading";
import {
  handleSelectAll,
  handleClearAll,
  handleSearch,
  handleDropdownClose,
  handleDropdownOpen,
  getPlaceholder,
  handleSelectAllWhenCompLoads,
  flattenOptions,
} from "./utils";
import { useClickOutside } from "./hooks/useClickOutside";
import { useKeyboardNavigation } from "./hooks/useKeyboardNavigation";
import { useTypeahead } from "./hooks/useTypeahead";
import { useScrollIntoView } from "./hooks/useScrollIntoView";
import "./Select.styles.scss";
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
import HelperText from "../common/HelperText";

const selectStyles = {
  menu: () => ({}), // to remove default menu styles
};

const SUBMENU_MAX_HEIGHT = 200;

export const Select = React.memo((props) => {
  const {
    isOpen,
    setIsOpen,
    label,
    isRequired,
    name,
    placeholder,
    searchPlaceholder = "Search here...",
    labelOrientation = "top",
    isMulti = false,
    isDisabled,
    isLoading,
    isWithIcon,
    isError,
    isWithSearch,
    isClearable,
    isWithSelectedOptionTags,
    toggleSelectAll,
    isSelectAll,
    icon,
    withPortal,
    dropDownPortalClassName,
    initialOptions,
    currentOptions,
    setCurrentOptions,
    selectedOptions = [],
    setSelectedOptions,
    portalContainer = document.body,
    isAgGridCellRenderer,
    onMenuScrollToBottom,
    setIsSelectAll,
    isWithSelectAll,
    isCloseWhenClickOutside = true,
    handleChange: externalOnChange,
    onSelectAll: externalOnSelectAll,
    onClearAll: externalOnClearAll,
    onSearch: externalOnSearch,
    onDropdownClose: externalOnDropdownClose,
    onDropdownOpen: externalOnDropdownOpen,
    minWidth,
    width,
    menuShouldBlockScroll = false,
    onBlur,
    isGrouped,
    selectId,
    column,
    customPlaceholderAfterSelect,
    isMultiInSubmenu = false,
    customBadgeLabel,
    customBadgeColor = "success",
    helperText,
    dropdownPosition,
    maxSelectableOptions,
    noOptionMessage = "No options available",
    isLoadingMore = false,
    onSearchBlur,
    showFooterMessage = {},
    selectionLabels = {},
  } = props;

  const [submenuOptions, setSubmenuOptions] = useState(null);
  const [submenuParent, setSubmenuParent] = useState(null);
  const flattenInitialOptions = flattenOptions(initialOptions);
  const [openToast, setOpenToast] = useState(false);
  const [toastMessage, setToastMessage] = useState("");
  const searchBarRef = useRef(null);
  const containerRef = useRef(null);
  const focusedIndex = useRef(0);
  const dropdownButtonRef = useRef(null);
  const textSpanRef = useRef(null);
  const [isTextTruncated, setIsTextTruncated] = useState(false);
  const memoizedOptions = useMemo(() => currentOptions, [currentOptions]);
  const flatOptions = useMemo(
    () => (isGrouped ? flattenOptions(currentOptions) : currentOptions),
    [currentOptions, isGrouped]
  );
  const submenuTimeoutRef = useRef(null);
  const [submenuPosition, setSubmenuPosition] = useState({
    top: 0,
    bottom: "auto",
    left: 0,
    width: 0,
  });
  const dropdownMenuRef = useRef(null);
  const menuRef = useRef(null);
  const [isSubmenuHovered, setIsSubmenuHovered] = useState(false);
  const [searchTerm, setSearchTerm] = useState("");
  const [isKeyboardNav, setIsKeyboardNav] = useState(false);
  const [submenuHighlightedIndex, setSubmenuHighlightedIndex] = useState(-1);
  const [isSubmenuKeyboardActive, setIsSubmenuKeyboardActive] = useState(false);
  const listboxId = useMemo(() => `ia-select-listbox-${selectId || Math.random().toString(36).slice(2, 9)}`, [selectId]);
  const listRef = useRef(null);

  const closeDropdown = useCallback((event) => {
    handleDropdownClose({
      externalOnDropdownClose,
      setCurrentOptions,
      initialOptions: isGrouped ? flattenInitialOptions : initialOptions,
      currentOptions,
      setIsOpen,
      onBlur,
      event,
    });
    setTimeout(() => dropdownButtonRef.current?.focus(), 0);
  }, [externalOnDropdownClose, setCurrentOptions, initialOptions, currentOptions, setIsOpen, onBlur, isGrouped, flattenInitialOptions]);

  const handleSelect = useCallback(
    (selectedValues, event, index) => {
      if (!isMulti) {
        searchBarRef?.current?.blur();
      }
      if (event?.action === "clear") {
        if (externalOnChange) {
          externalOnChange([], event, index);
        }
        return;
      }

      // Multi-select: handle parent with children
      if (isMulti) {
        let newSelectedOptions = Array.isArray(selectedOptions)
          ? [...selectedOptions]
          : [];
        const option = event?.option || selectedValues;
        const isParent =
          option && option.children && option.children.length > 0;
        const isSelected = newSelectedOptions.some(
          (sel) => sel.value === option.value
        );

        // Get current count for limit checking
        const currentCount =
          maxSelectableOptions !== undefined
            ? countTotalSelectedOptions(selectedOptions)
            : 0;

        if (isParent) {
          // If selecting a parent
          if (!isSelected) {
            // Check if adding parent would exceed maxSelectableOptions (parent level only)
            if (maxSelectableOptions !== undefined) {
              if (currentCount >= maxSelectableOptions) {
                return;
              }
            }
            // Add parent with all its children
            newSelectedOptions.push({
              ...option,
              children: option.children,
            });
          } else {
            // Remove parent and all its children
            newSelectedOptions = newSelectedOptions.filter(
              (sel) => sel.value !== option.value
            );
          }
        } else {
          // If selecting a child or a regular option
          const parentOption = (initialOptions || []).find(
            (parent) =>
              parent.children &&
              parent.children.some((child) => child.value === option.value)
          );

          if (parentOption) {
            // Handle child selection
            const parentIndex = newSelectedOptions.findIndex(
              (sel) => sel.value === parentOption.value
            );

            if (isSelected) {
              // Remove the child from parent's children
              if (parentIndex !== -1) {
                const parent = newSelectedOptions[parentIndex];
                parent.children = parent.children.filter(
                  (child) => child.value !== option.value
                );

                // If no children left, remove the parent
                if (parent.children.length === 0) {
                  newSelectedOptions = newSelectedOptions.filter(
                    (sel) => sel.value !== parentOption.value
                  );
                }
              }
            } else {
              // Add the child to parent's children
              if (parentIndex !== -1) {
                // Parent exists, add child to its children if not already present
                // No limit check needed here since we're only counting at parent level
                const parent = newSelectedOptions[parentIndex];
                if (
                  !parent.children.some((child) => child.value === option.value)
                ) {
                  parent.children.push(option);
                }
              } else {
                // Parent doesn't exist, add parent with this child
                // Check maxSelectableOptions limit before adding new parent
                if (maxSelectableOptions !== undefined) {
                  if (currentCount >= maxSelectableOptions) {
                    return;
                  }
                }
                newSelectedOptions.push({
                  ...parentOption,
                  children: [option],
                });
              }
            }
          } else {
            // Handle regular option selection (no parent)
            if (isSelected) {
              // Remove the option
              newSelectedOptions = newSelectedOptions.filter(
                (sel) => sel.value !== option.value
              );
            } else {
              // Check maxSelectableOptions limit before adding regular option
              if (maxSelectableOptions !== undefined) {
                if (currentCount >= maxSelectableOptions) {
                  return;
                }
              }
              // Add the option
              newSelectedOptions.push(option);
            }
          }
        }

        setSelectedOptions(newSelectedOptions);
        setIsSelectAll(newSelectedOptions.length === initialOptions.length);

        if (externalOnChange) {
          externalOnChange(newSelectedOptions, event, index);
        }
        return;
      }

      if (isGrouped && isMulti) {
        const flattenSelectedValues = flattenOptions(selectedValues);
        setSelectedOptions(flattenSelectedValues);
        setIsSelectAll(
          flattenSelectedValues.length === flattenInitialOptions.length
        );
        if (externalOnChange) {
          externalOnChange(flattenSelectedValues, event, index);
        }
      } else {
        setSelectedOptions(selectedValues);
        if (externalOnChange) {
          externalOnChange(selectedValues, event, index);
        }
      }

      if (isMulti && !isGrouped) {
        if (initialOptions.length > 0)
          setIsSelectAll(selectedValues.length === initialOptions.length);
        else setIsSelectAll(selectedValues.length === currentOptions.length);
      }

      if (!isMulti) {
        handleDropdownClose({
          externalOnDropdownClose,
          setCurrentOptions,
          initialOptions,
          currentOptions,
          setIsOpen,
          undefined, // TODO: implement other solution for single select
          event,
        });
      }
    },
    [
      isMulti,
      setIsSelectAll,
      setIsOpen,
      externalOnChange,
      initialOptions,
      onBlur,
      selectedOptions,
      setSelectedOptions,
      setIsSelectAll,
      flattenInitialOptions,
      isGrouped,
      currentOptions,
      maxSelectableOptions,
    ]
  );
  
  const getOptionDisabled = useCallback((opt) => {
    return !!(opt?.disabled || opt?.isDisabled);
  }, []);

  const hasSelectAll = !!(isMulti && toggleSelectAll && !isLoading);

  const handleSelectAllToggle = useCallback(() => {
    const syntheticEvent = { target: { checked: !isSelectAll } };
    if (externalOnSelectAll) {
      externalOnSelectAll(syntheticEvent);
    } else {
      if (!isSelectAll) {
        const restCurrentOptions = currentOptions.filter(
          (option) =>
            !selectedOptions.find(
              (sel) =>
                sel.label === option.label && option.value === sel.value
            )
        );
        const newSelected = [...selectedOptions, ...restCurrentOptions];
        setIsSelectAll(true);
        setSelectedOptions(newSelected);
        if (externalOnChange) externalOnChange(newSelected);
      } else {
        setIsSelectAll(false);
        setSelectedOptions([]);
        if (externalOnChange) externalOnChange([]);
      }
    }
  }, [isSelectAll, externalOnChange, externalOnSelectAll, currentOptions, selectedOptions, setSelectedOptions]);

  const handleOptionSelect = useCallback((opt, index) => {
    if (opt?.children?.length > 0) {
      // Parent with children: open submenu via keyboard
      setSubmenuOptions(opt.children);
      setSubmenuParent(opt);
      setIsSubmenuKeyboardActive(true);
      setSubmenuHighlightedIndex(0);
      // Compute submenu position
      const optionNodes = dropdownMenuRef.current?.querySelectorAll('[role="option"]');
      const optionNode = optionNodes?.[index];
      const dropdownRect = dropdownMenuRef.current?.getBoundingClientRect();
      const optionRect = optionNode?.getBoundingClientRect();
      if (dropdownRect && optionRect) {
        const spaceBelow = window.innerHeight - optionRect.bottom;
        if (spaceBelow < SUBMENU_MAX_HEIGHT) {
          setSubmenuPosition({
            top: "auto",
            bottom: dropdownRect.bottom - optionRect.bottom,
            left: dropdownRect.width + 12,
            width: dropdownRect.width,
          });
        } else {
          setSubmenuPosition({
            top: optionRect.top - dropdownRect.top,
            bottom: "auto",
            left: dropdownRect.width + 12,
            width: dropdownRect.width,
          });
        }
      }
      return;
    }

    // Leaf option: delegate to react-select's onChange path via handleSelect
    const actionMeta = { option: opt, action: "select-option" };
    if (isMulti) {
      // Multi: toggle option via handleSelect (it already handles add/remove)
      handleSelect(selectedOptions, actionMeta, index);
    } else {
      // Single: select and close
      actionMeta.option = opt;
      handleSelect(opt, actionMeta, index);
      closeDropdown();
    }
  }, [isMulti, selectedOptions, closeDropdown, handleSelect]);

  const {
    highlightedIndex,
    setHighlightedIndex,
    handleKeyDown: navKeyDown,
  } = useKeyboardNavigation({
    options: flatOptions,
    isOpen,
    onSelect: handleOptionSelect,
    onClose: closeDropdown,
    isMulti,
    selectedOption: isMulti ? null : selectedOptions,
    selectedOptions: isMulti ? selectedOptions : [],
    getOptionDisabled,
    hasSelectAll,
    onSelectAllToggle: handleSelectAllToggle,
    onNavigateUp: isWithSearch && !hasSelectAll
      ? () => {
          setIsKeyboardNav(false);
          searchBarRef.current?.focus();
        }
      : undefined,
  });

  const { handleTypeahead, resetBuffer } = useTypeahead({
    options: flatOptions,
    setHighlightedIndex,
    isActive: isOpen && !isWithSearch,
  });

  useScrollIntoView({
    highlightedIndex,
    listRef,
    isVirtualized: !isGrouped,
    containerRef: dropdownMenuRef,
  });

  // Shared submenu keyboard handler - returns true if event was consumed
  const handleSubmenuKeyDown = useCallback(
    (e) => {
      if (isSubmenuKeyboardActive && submenuOptions) {
        switch (e.key) {
          case "ArrowDown":
            e.preventDefault();
            setSubmenuHighlightedIndex((prev) =>
              prev < submenuOptions.length - 1 ? prev + 1 : 0
            );
            return true;
          case "ArrowUp":
            e.preventDefault();
            setSubmenuHighlightedIndex((prev) =>
              prev > 0 ? prev - 1 : submenuOptions.length - 1
            );
            return true;
          case "ArrowLeft":
            e.preventDefault();
            setIsSubmenuKeyboardActive(false);
            setSubmenuOptions(null);
            setSubmenuParent(null);
            setSubmenuHighlightedIndex(-1);
            return true;
          case "Escape":
            e.preventDefault();
            setIsSubmenuKeyboardActive(false);
            setSubmenuOptions(null);
            setSubmenuParent(null);
            setSubmenuHighlightedIndex(-1);
            return true;
          case "Enter":
          case " ":
            e.preventDefault();
            if (
              submenuHighlightedIndex >= 0 &&
              submenuHighlightedIndex < submenuOptions.length
            ) {
              const submenuEl =
                dropdownMenuRef.current?.querySelector(".ia-select-submenu");
              const optionEls =
                submenuEl?.querySelectorAll(".select-option-content");
              optionEls?.[submenuHighlightedIndex]?.click();
            }
            return true;
          default:
            return true;
        }
      }

      if (e.key === "ArrowRight" && highlightedIndex >= 0) {
        const currentOpt = flatOptions[highlightedIndex];
        if (currentOpt?.children?.length > 0) {
          e.preventDefault();
          handleOptionSelect(currentOpt, highlightedIndex);
          return true;
        }
      }

      return false;
    },
    [
      isSubmenuKeyboardActive,
      submenuOptions,
      submenuHighlightedIndex,
      highlightedIndex,
      flatOptions,
      handleOptionSelect,
    ]
  );

  // Reset typeahead buffer when dropdown closes
  useEffect(() => {
    if (!isOpen) {
      resetBuffer();
      setIsKeyboardNav(false);
      setIsSubmenuKeyboardActive(false);
      setSubmenuHighlightedIndex(-1);
    }
  }, [isOpen, resetBuffer]);

  // Auto-focus search input when dropdown opens
  useEffect(() => {
    if (isOpen && isWithSearch) {
      setTimeout(() => searchBarRef.current?.focus(), 0);
    }
  }, [isOpen, isWithSearch]);

  // Get column width from column state
  const [columnWidth, setColumnWidth] = useState(
    (column?.getActualWidth?.() || column?.getWidth?.()) - 12
  );

  // Check if text is truncated
  useEffect(() => {
    if (textSpanRef.current) {
      const isTruncated =
        textSpanRef.current.scrollWidth > textSpanRef.current.clientWidth;
      setIsTextTruncated(isTruncated);
    }
  }, [columnWidth, currentOptions, selectedOptions, placeholder]);

  // Add effect to force re-render on column width changes
  useEffect(() => {
    if (isAgGridCellRenderer && column) {
      const handleColumnResized = () => {
        const newWidth = column.getActualWidth?.() || column.getWidth?.();
        setColumnWidth(newWidth - 12);
      };

      column.addEventListener("widthChanged", handleColumnResized);
      return () => {
        column.removeEventListener("widthChanged", handleColumnResized);
      };
    }
  }, [isAgGridCellRenderer, column, columnWidth]);

  // Use the click outside hook
  useClickOutside({
    isOpen,
    containerRef,
    menuRef,
    isCloseWhenClickOutside,
    onClose: (event) => {
      handleDropdownClose({
        externalOnDropdownClose,
        setCurrentOptions,
        initialOptions: isGrouped ? flattenInitialOptions : initialOptions,
        currentOptions,
        setIsOpen,
        onBlur,
        event,
      });
    },
  });

  useEffect(() => {
    if (isWithSelectAll) {
      handleSelectAllWhenCompLoads({
        currentOptions,
        selectedOptions,
        setSelectedOptions,
        ...props,
      });
    }
  }, [isWithSelectAll]);

  // Helper to sync parent/child selection after any change
  function syncParentChildSelection(selectedArr) {
    // Only one level deep
    if (!selectedArr || selectedArr.length === 0) {
      setSelectedOptions([]);
      setIsSelectAll(false);
      return;
    }
    let updated = [...selectedArr];
    (initialOptions || []).forEach((parent) => {
      if (parent.children && parent.children.length > 0) {
        const allChildrenSelected = parent.children.every((child) =>
          updated.some((sel) => sel.value === child.value)
        );
        const parentSelected = updated.some(
          (sel) => sel.value === parent.value
        );
        if (allChildrenSelected && !parentSelected) {
          updated.push(parent);
        } else if (!allChildrenSelected && parentSelected) {
          updated = updated.filter((sel) => sel.value !== parent.value);
        }
      }
    });
    setSelectedOptions(updated);
    setIsSelectAll(
      updated.length ===
        (initialOptions.length > 0
          ? initialOptions.length
          : currentOptions.length)
    );
  }

  const handleOptionHover = useCallback(
    (option, index, event) => {
      if (submenuTimeoutRef.current) {
        clearTimeout(submenuTimeoutRef.current);
      }
      if (option?.children?.length > 0) {
        const optionNode = event?.currentTarget;
        const dropdownRect = dropdownMenuRef.current?.getBoundingClientRect();
        const optionRect = optionNode?.getBoundingClientRect();
        if (dropdownRect && optionRect) {
          const spaceBelow = window.innerHeight - optionRect.bottom;
          const openUpward = spaceBelow < SUBMENU_MAX_HEIGHT;
          if (openUpward) {
            setSubmenuPosition({
              top: "auto",
              bottom: dropdownRect.bottom - optionRect.bottom,
              left: dropdownRect.width + 12,
              width: dropdownRect.width,
            });
          } else {
            setSubmenuPosition({
              top: optionRect.top - dropdownRect.top,
              bottom: "auto",
              left: dropdownRect.width + 12,
              width: dropdownRect.width,
            });
          }
        }
        setSubmenuOptions(option.children);
        setSubmenuParent(option);
        setIsSubmenuHovered(true);
      } else {
        setIsSubmenuHovered(false);
        setSubmenuOptions(null);
        setSubmenuParent(null);
      }
    },
    [isSubmenuHovered]
  );

  useEffect(() => {
    return () => {
      if (submenuTimeoutRef.current) {
        clearTimeout(submenuTimeoutRef.current);
      }
    };
  }, []);

  // Helper to get all options (parents and children)
  function getAllOptions(options) {
    let all = [];
    (options || []).forEach((opt) => {
      all.push(opt);
      if (opt.children && opt.children.length > 0) {
        all = all.concat(getAllOptions(opt.children));
      }
    });
    return all;
  }

  // Helper to count total selected options at parent level only
  function countTotalSelectedOptions(selectedOptions) {
    if (
      !selectedOptions ||
      (Array.isArray(selectedOptions) && selectedOptions.length === 0)
    ) {
      return 0;
    }

    if (!isMulti) {
      // For single select, count as 1 if selected
      return selectedOptions.value ? 1 : 0;
    }

    // For multi-select, count only parent-level options (not children)
    const selectedArray = Array.isArray(selectedOptions) ? selectedOptions : [];

    // Count only parent options - each item in selectedOptions is a parent-level selection
    return selectedArray.length;
  }

  // Check if maxSelectableOptions limit is reached
  const totalSelectedCount = useMemo(() => {
    return countTotalSelectedOptions(selectedOptions);
  }, [selectedOptions, isMulti]);

  const isMaxLimitReached = useMemo(() => {
    return (
      maxSelectableOptions !== undefined &&
      totalSelectedCount >= maxSelectableOptions
    );
  }, [maxSelectableOptions, totalSelectedCount]);

  // Update handleSelectAll logic
  function handleSelectAllWrapper({
    event,
    externalOnChange,
    setIsSelectAll,
    initialOptions,
    setSelectedOptions,
  }) {
    if (externalOnSelectAll) {
      externalOnSelectAll(event);
    } else {
      if (event && event.target.checked) {
        setIsSelectAll(true);

        //currentOptions without selectedOptions
        const restCurrentOptions = currentOptions.filter(
          (option) =>
            !selectedOptions.find(
              (selectedOption) =>
                selectedOption.label === option.label &&
                option.value === selectedOption.value
            )
        );
        setSelectedOptions([...selectedOptions, ...restCurrentOptions]);
        if (externalOnChange)
          externalOnChange([...selectedOptions, ...restCurrentOptions]);
      } else {
        setIsSelectAll(false);
        setSelectedOptions([]);
        if (externalOnChange) externalOnChange([]);
      }
    }
  }

  // Update handleSelectAllWhenCompLoads logic
  function handleSelectAllWhenCompLoadsWrapper({
    currentOptions,
    selectedOptions,
    setSelectedOptions,
  }) {
    setSelectedOptions(getAllOptions(currentOptions));
  }

  // Update handleClearAll logic
  function handleClearAllWrapper({
    externalOnClearAll,
    setSelectedOptions,
    setIsSelectAll,
    handleSelect,
    syncParentChildSelection,
  }) {
    if (externalOnClearAll) {
      externalOnClearAll();
      setSelectedOptions([]);
      setIsSelectAll(false);
    } else {
      handleSelect([], { action: "clear" });
      setSelectedOptions([]);
      setIsSelectAll(false);
    }
    syncParentChildSelection([]);
  }

  if (isMulti && !setIsSelectAll) {
    return (
      <Alert
        description="isMulti cannot be used without isSelectAll & setIsSelectAll"
        title="Select Error"
        severity="error"
      />
    );
  }

  return (
    <div
      className={`ia-select-main-container-v3 ${
        labelOrientation == "top" ? "top-orientation" : ""
      } ${isAgGridCellRenderer ? "isAgGridCellRenderer" : ""}`}
    >
      {label && (
        <div className="ia-select-label-v3">
          {label} {isRequired && <span style={{ color: "red" }}>*</span>}
        </div>
      )}
      <div
        ref={containerRef}
        style={{
          width: isAgGridCellRenderer ? "100%" : minWidth ?? width ?? "auto",
          minWidth: isAgGridCellRenderer ? "0" : minWidth ?? width ?? "auto",
          maxWidth: isAgGridCellRenderer ? columnWidth || "100%" : "none",
        }}
      >
        <Dropdown
          dropdownPosition={dropdownPosition}
          isOpen={isOpen}
          onClose={(event) => {
            handleDropdownClose({
              externalOnDropdownClose,
              setCurrentOptions,
              initialOptions,
              currentOptions,
              setIsOpen,
              onBlur,
              event,
            });
          }}
          disabled={isDisabled}
          containerRef={containerRef}
          menuRef={menuRef}
          withPortal={withPortal}
          portalContainer={portalContainer}
          dropDownPortalClassName={dropDownPortalClassName}
          dropdownButtonRef={dropdownButtonRef}
          target={
            <>
              <button
                name={name}
                id={selectId}
                role="combobox"
                aria-haspopup="listbox"
                aria-expanded={!!isOpen}
                aria-controls={isOpen ? listboxId : undefined}
                aria-activedescendant={
                  isOpen && highlightedIndex >= 0
                    ? `${listboxId}-option-${highlightedIndex}`
                    : undefined
                }
                className={`ia-select-styled-dropdown-main-button ${
                  isError ? "impact-select-error" : ""
                } ${isDisabled ? "impact-select-disabled" : ""} ${
                  isClearable ? "is-with-clearable" : ""
                } ${isOpen && isKeyboardNav && isWithSearch ? "ia-select-button-keyboard-open" : ""}`}
                style={{
                  minWidth: isAgGridCellRenderer ? "0" : minWidth ?? "240px",
                  width: isAgGridCellRenderer
                    ? "100%"
                    : width ?? minWidth ?? "240px",
                  maxWidth: isAgGridCellRenderer
                    ? columnWidth || "100%"
                    : "300px",
                  flex: isAgGridCellRenderer ? "1 1 auto" : "none",
                }}
                variant="primary"
                disabled={isDisabled}
                onBlur={(e) => {
                  if (!isMulti) {
                    e.preventDefault();
                    e.stopPropagation();
                    e.target.value = selectedOptions?.value;
                    if (onBlur) onBlur(e);
                  }
                }}
                onClick={(e) => {
                  e.preventDefault();
                  e.stopPropagation();
                  setIsKeyboardNav(false);
                  isOpen
                    ? handleDropdownClose({
                        externalOnDropdownClose,
                        setCurrentOptions,
                        initialOptions,
                        currentOptions,
                        setIsOpen,
                        onBlur,
                        event: e,
                      })
                    : handleDropdownOpen({
                        externalOnDropdownOpen,
                        isOpen,
                        setIsOpen,
                      });
                }}
                onKeyDown={(e) => {
                  if (!isOpen) {
                    if (e.key === "Enter" || e.key === " " || e.key === "ArrowDown" || e.key === "ArrowUp") {
                      e.preventDefault();
                      setIsKeyboardNav(true);
                      handleDropdownOpen({ externalOnDropdownOpen, isOpen, setIsOpen });
                      return;
                    }
                    return;
                  }
                  setIsKeyboardNav(true);

                  if (handleSubmenuKeyDown(e)) return;

                  if (!isWithSearch) {
                    const consumed = handleTypeahead(e);
                    if (consumed) return;
                  }
                  navKeyDown(e);
                }}
                ref={dropdownButtonRef}
              >
                <div
                  className={`ia-select-button-text ${
                    getPlaceholder(
                      isMulti,
                      selectedOptions,
                      placeholder,
                      customPlaceholderAfterSelect,
                      selectionLabels
                    ) === placeholder
                      ? "placeholder"
                      : ""
                  } ${
                    !(
                      (isClearable && selectedOptions) ||
                      (isMulti &&
                        selectedOptions &&
                        selectedOptions.length > 0 &&
                        isClearable)
                    )
                      ? "ia-select-button-text-full-width"
                      : ""
                  } ${isAgGridCellRenderer ? "impact-select-table" : ""}`}
                >
                  {isWithIcon && { ...icon }}
                  {isTextTruncated ? (
                    <Tooltip
                      title={getPlaceholder(
                        isMulti,
                        selectedOptions,
                        placeholder
                      )}
                      variant="tertiary"
                      orientation="top"
                    >
                      <span
                        ref={textSpanRef}
                        className="ia-select-button-text-span"
                      >
                        {isMultiInSubmenu &&
                        !isMulti &&
                        selectedOptions &&
                        selectedOptions.children &&
                        selectedOptions.children.length > 0
                          ? selectedOptions.children.length === 1
                            ? selectedOptions.children[0].label
                            : `${selectionLabels.selected || "Selected"} (${selectedOptions.children.length})`
                          : getPlaceholder(
                              isMulti,
                              selectedOptions,
                              placeholder,
                              customPlaceholderAfterSelect,
                              selectionLabels
                            )}
                      </span>
                    </Tooltip>
                  ) : (
                    <span
                      ref={textSpanRef}
                      className="ia-select-button-text-span"
                    >
                      {!isMulti &&
                      selectedOptions &&
                      selectedOptions.children &&
                      selectedOptions.children.length > 0
                        ? selectedOptions.children.length === 1
                          ? selectedOptions.children[0].label
                          : `${selectionLabels.selected || "Selected"} (${selectedOptions.children.length})`
                        : getPlaceholder(
                            isMulti,
                            selectedOptions,
                            placeholder,
                            customPlaceholderAfterSelect,
                            selectionLabels
                          )}
                    </span>
                  )}
                </div>
                {isMulti &&
                  selectedOptions &&
                  selectedOptions.length > 0 &&
                  isClearable && (
                    <div
                      className="ia-select-button-clear-icon"
                      role="button"
                      tabIndex={0}
                      aria-label="Clear selection"
                      onClick={(event) => {
                        event.stopPropagation();
                        if (externalOnClearAll) {
                          externalOnClearAll();
                        } else {
                          setSelectedOptions([]);
                          setIsSelectAll(false);
                          syncParentChildSelection([]);
                        }
                      }}
                      onKeyDown={(event) => {
                        if (event.key === "Enter" || event.key === " ") {
                          event.preventDefault();
                          event.stopPropagation();
                          if (externalOnClearAll) {
                            externalOnClearAll();
                          } else {
                            setSelectedOptions([]);
                            setIsSelectAll(false);
                            syncParentChildSelection([]);
                          }
                        }
                      }}
                    />
                  )}
                {!isMulti &&
                  isClearable &&
                  selectedOptions &&
                  Object.keys(selectedOptions).length > 0 && (
                    <div
                      className="ia-select-button-clear-icon"
                      role="button"
                      tabIndex={0}
                      aria-label="Clear selection"
                      onClick={(event) => {
                        event.stopPropagation();
                        if (externalOnClearAll) {
                          externalOnClearAll();
                        } else {
                          setSelectedOptions([]);
                          setIsSelectAll(false);
                          syncParentChildSelection([]);
                        }
                      }}
                      onKeyDown={(event) => {
                        if (event.key === "Enter" || event.key === " ") {
                          event.preventDefault();
                          event.stopPropagation();
                          if (externalOnClearAll) {
                            externalOnClearAll();
                          } else {
                            setSelectedOptions([]);
                            setIsSelectAll(false);
                            syncParentChildSelection([]);
                          }
                        }
                      }}
                    />
                  )}
                <div
                  className={`ia-select-chevron-icon ${isOpen ? "open" : ""} ${
                    isDisabled ? "disabled" : ""
                  }`}
                />
              </button>
              {helperText && (
                <HelperText
                  helper={isError ? helperText : ""}
                  error={isError}
                  minWidth={minWidth}
                />
              )}
              {isMulti && isWithSelectedOptionTags && (
                <SelectedOptionsTags
                  selectedOptions={selectedOptions}
                  setSelectedOptions={setSelectedOptions}
                  onChange={handleSelect}
                />
              )}
            </>
          }
          isKeyboardNav={isKeyboardNav}
        >
          <SearchFilter
            ref={searchBarRef}
            onSearch={(event) =>
              handleSearch({
                isMulti,
                event,
                externalOnSearch,
                initialOptions,
                setCurrentOptions,
                setOpenToast,
                setToastMessage,
                setSearchTerm,
              })
            }
            isMulti={isMulti}
            onSelectAll={(event) =>
              handleSelectAllWrapper({
                event,
                externalOnChange,
                setIsSelectAll,
                initialOptions,
                setSelectedOptions,
              })
            }
            onClearAll={() => {
              handleClearAllWrapper({
                externalOnClearAll,
                setSelectedOptions,
                setIsSelectAll,
                handleSelect,
                syncParentChildSelection,
              });
            }}
            isSelectAll={isSelectAll}
            selectedOptions={selectedOptions}
            toggleSelectAll={toggleSelectAll}
            isWithSearch={isWithSearch}
            setSelectedOptions={setSelectedOptions}
            onKeyDown={navKeyDown}
            onSubmenuKeyDown={handleSubmenuKeyDown}
            onClose={closeDropdown}
            setHighlightedIndex={setHighlightedIndex}
            setIsKeyboardNav={setIsKeyboardNav}
            highlightedIndex={highlightedIndex}
            isSelectAllHighlighted={isKeyboardNav && hasSelectAll && highlightedIndex === -1}
            isClearable={isClearable}
            searchPlaceholder={searchPlaceholder}
            isLoading={isLoading}
            isLoadingMore={isLoadingMore}
            searchTerm={searchTerm}
            externalOnSearch={externalOnSearch}
            setSearchTerm={setSearchTerm}
            onSearchBlur={onSearchBlur}
            selectionLabels={selectionLabels}
          />
          <div className="ia-select-dropdown-container" ref={dropdownMenuRef}>
            <ReactSelect
              {...props}
              className="ia-select-dropdown-v3"
              classNames={{
                option: ({ data }) => {
                  const optIdx = flatOptions.findIndex(
                    (o) => o.value === data?.value
                  );
                  return `ia-select-option${
                    submenuParent?.value === data?.value
                      ? " submenu-active"
                      : ""
                  }${
                    isKeyboardNav && optIdx >= 0 && optIdx === highlightedIndex
                      ? " ia-select-option-highlighted"
                      : ""
                  }`;
                },
              }}
              isMulti={isMulti}
              autoFocus
              backspaceRemovesValue={false}
              components={{
                IndicatorSeparator: null,
                Option: (optionProps) => {
                  const optionIndex = flatOptions.findIndex(
                    (opt) => opt.value === optionProps.data.value
                  );

                  // Check if it's a child option
                  const parentOption = (initialOptions || []).find(
                    (parent) =>
                      parent.children &&
                      parent.children.some(
                        (child) => child.value === optionProps.data.value
                      )
                  );

                  let isSelected;
                  if (!isMulti) {
                    if (isMultiInSubmenu) {
                      // For isMultiInSubmenu mode
                      if (parentOption) {
                        // For child options, check if this child is selected
                        isSelected =
                          selectedOptions &&
                          selectedOptions.children &&
                          selectedOptions.children.some(
                            (child) => child.value === optionProps.data.value
                          );
                      } else if (optionProps.data.children) {
                        // For parent options, check if any of its children are selected
                        isSelected =
                          selectedOptions &&
                          selectedOptions.children &&
                          selectedOptions.children.length > 0 &&
                          selectedOptions.value === optionProps.data.value;
                      } else {
                        // For regular options
                        isSelected =
                          selectedOptions &&
                          selectedOptions.value === optionProps.data.value;
                      }
                    } else {
                      // Normal single select behavior
                      if (parentOption) {
                        // For child options, check if this child is in selected parent's children
                        isSelected =
                          selectedOptions &&
                          selectedOptions.children &&
                          selectedOptions.children.some(
                            (child) => child.value === optionProps.data.value
                          );
                      } else if (optionProps.data.children) {
                        // For parent options, check if this parent has selected children
                        isSelected =
                          selectedOptions &&
                          selectedOptions.value === optionProps.data.value;
                      } else {
                        // For regular options
                        isSelected =
                          selectedOptions &&
                          selectedOptions.value === optionProps.data.value;
                      }
                    }
                  } else {
                    // Multi select behavior remains unchanged
                    if (parentOption) {
                      const selectedParent = Array.isArray(selectedOptions)
                        ? selectedOptions.find(
                            (sel) => sel.value === parentOption.value
                          )
                        : null;
                      isSelected =
                        selectedParent &&
                        selectedParent.children.some(
                          (child) => child.value === optionProps.data.value
                        );
                    } else {
                      isSelected = Array.isArray(selectedOptions)
                        ? selectedOptions.some(
                            (sel) => sel.value === optionProps.data.value
                          )
                        : false;
                    }
                  }

                  // Check if this option should be disabled due to maxSelectableOptions
                  const shouldDisableOption =
                    isMaxLimitReached && !isSelected && isMulti;

                  return (
                    <Option
                      {...optionProps}
                      isSelected={isSelected}
                      selectedOptions={selectedOptions}
                      initialOptions={initialOptions}
                      isDisabled={
                        shouldDisableOption ||
                        optionProps?.data?.disabled ||
                        optionProps?.data?.isDisabled
                      }
                      customOptionProps={{
                        onMouseEnter: (e) => {
                          handleOptionHover(optionProps.data, optionIndex, e);
                        },
                      }}
                    />
                  );
                },
                ...(!isGrouped && { MenuList }),
                ...(isGrouped && {
                  GroupHeading: (props) => (
                    <CustomGroupHeading
                      {...props}
                      customBadgeLabel={customBadgeLabel}
                      customBadgeColor={customBadgeColor}
                    />
                  ),
                }),
              }}
              controlShouldRenderValue={true}
              hideSelectedOptions={false}
              isClearable={isClearable}
              menuIsOpen
              tabSelectsValue={false}
              onChange={(selectedOptions, actionMeta) => {
                const option = actionMeta?.option;
                const index = flatOptions.findIndex(
                  (opt) =>
                    opt.value === (option?.value || selectedOptions?.value)
                );
                if (!isMulti) {
                  actionMeta.option = selectedOptions;
                }
                handleSelect(selectedOptions, actionMeta, index);
              }}
              options={memoizedOptions}
              placeholder="Search..."
              value={selectedOptions}
              styles={selectStyles}
              isLoading={isLoading}
              isLoadingMore={isLoadingMore}
              onMenuScrollToBottom={onMenuScrollToBottom}
              menuShouldBlockScroll={menuShouldBlockScroll}
              captureMenuScroll={false}
              noOptionMessage={noOptionMessage}
              listboxId={listboxId}
              highlightedIndex={highlightedIndex}
              setHighlightedIndex={setHighlightedIndex}
              isKeyboardNav={isKeyboardNav}
              setIsKeyboardNav={setIsKeyboardNav}
              listRef={listRef}
              submenuParent={submenuParent}
            />
            {submenuOptions && (
              <div
                className="ia-select-submenu"
                style={{
                  position: "absolute",
                  top: submenuPosition.top,
                  bottom: submenuPosition.bottom,
                  left: submenuPosition.left,
                  width: submenuPosition.width,
                }}
                onMouseEnter={() => {
                  setIsSubmenuHovered(true);
                  if (submenuTimeoutRef.current) {
                    clearTimeout(submenuTimeoutRef.current);
                  }
                }}
                onMouseLeave={() => {
                  setIsSubmenuHovered(false);
                  submenuTimeoutRef.current = setTimeout(() => {
                    if (!isSubmenuHovered) {
                      setSubmenuOptions(null);
                      setSubmenuParent(null);
                    }
                  }, 100);
                }}
              >
                <div className="ia-select-submenu-content" role="listbox" aria-label="Submenu options">
                  {submenuOptions.map((option, subIdx) => {
                    // For single select with multi submenu, check if this child is selected
                    const isChildSelected = !isMulti
                      ? isMultiInSubmenu
                        ? selectedOptions &&
                          selectedOptions.children &&
                          selectedOptions.children.some(
                            (child) => child.value === option.value
                          )
                        : selectedOptions &&
                          selectedOptions.children &&
                          selectedOptions.children.some(
                            (child) => child.value === option.value
                          )
                      : (() => {
                          const selectedOptionsArray = Array.isArray(
                            selectedOptions
                          )
                            ? selectedOptions
                            : [];
                          const parentOption = selectedOptionsArray.find(
                            (sel) => sel.value === submenuParent.value
                          );
                          return parentOption
                            ? parentOption.children.some(
                                (child) => child.value === option.value
                              )
                            : false;
                        })();

                    // Children should never be disabled based on maxSelectableOptions
                    // since we only count at parent level
                    const shouldDisableSubmenuOption = false;
                    const isSubHighlighted = isSubmenuKeyboardActive && subIdx === submenuHighlightedIndex;

                    return (
                      <div
                        key={option.value}
                        role="option"
                        aria-selected={!!isChildSelected}
                        id={`${listboxId}-submenu-option-${subIdx}`}
                        className={`select-option-content${
                          isChildSelected ? " selected" : ""
                        } ${shouldDisableSubmenuOption ? " disabled" : ""}${
                          isSubHighlighted ? " ia-select-option-highlighted" : ""
                        }`}
                        onClick={(event) => {
                          if (shouldDisableSubmenuOption) {
                            event.stopPropagation();
                            return;
                          }
                          if (!isMulti) {
                            if (isMultiInSubmenu) {
                              // Handle multi-select in submenu for single select mode
                              if (isChildSelected) {
                                // If child is already selected, remove it
                                if (
                                  selectedOptions &&
                                  selectedOptions.children
                                ) {
                                  const updatedChildren =
                                    selectedOptions.children.filter(
                                      (child) => child.value !== option.value
                                    );
                                  if (updatedChildren.length === 0) {
                                    // If no children left, remove the parent completely
                                    setSelectedOptions(null);
                                    if (externalOnChange) {
                                      externalOnChange(null, { option }, null);
                                    }
                                  } else {
                                    const newSelectedOptions = {
                                      ...selectedOptions,
                                      children: updatedChildren,
                                    };
                                    setSelectedOptions(newSelectedOptions);
                                    if (externalOnChange) {
                                      externalOnChange(
                                        newSelectedOptions,
                                        { option },
                                        null
                                      );
                                    }
                                  }
                                }
                              } else {
                                // If child is not selected, add it
                                if (!selectedOptions) {
                                  // First selection - initialize with current parent
                                  // Check maxSelectableOptions limit before adding new parent
                                  if (maxSelectableOptions !== undefined) {
                                    const currentCount =
                                      countTotalSelectedOptions(
                                        selectedOptions
                                      );
                                    if (currentCount >= maxSelectableOptions) {
                                      return;
                                    }
                                  }
                                  const newSelectedOptions = {
                                    ...submenuParent,
                                    children: [option],
                                  };
                                  setSelectedOptions(newSelectedOptions);
                                  if (externalOnChange) {
                                    externalOnChange(
                                      newSelectedOptions,
                                      { option },
                                      null
                                    );
                                  }
                                } else if (
                                  selectedOptions.value === submenuParent.value
                                ) {
                                  // Same parent - add to existing children (no limit check needed)
                                  const newSelectedOptions = {
                                    ...selectedOptions,
                                    children: [
                                      ...(selectedOptions.children || []),
                                      option,
                                    ],
                                  };
                                  setSelectedOptions(newSelectedOptions);
                                  if (externalOnChange) {
                                    externalOnChange(
                                      newSelectedOptions,
                                      { option },
                                      null
                                    );
                                  }
                                } else {
                                  // Different parent - replace with new parent and child
                                  // Check maxSelectableOptions limit before adding new parent
                                  if (maxSelectableOptions !== undefined) {
                                    const currentCount =
                                      countTotalSelectedOptions(
                                        selectedOptions
                                      );
                                    if (currentCount >= maxSelectableOptions) {
                                      return;
                                    }
                                  }
                                  const newSelectedOptions = {
                                    ...submenuParent,
                                    children: [option],
                                  };
                                  setSelectedOptions(newSelectedOptions);
                                  if (externalOnChange) {
                                    externalOnChange(
                                      newSelectedOptions,
                                      { option },
                                      null
                                    );
                                  }
                                }
                              }
                            } else {
                              // Normal single select behavior - always pass parent with selected child
                              const newSelectedOptions = {
                                ...submenuParent,
                                children: [option],
                              };
                              setSelectedOptions(newSelectedOptions);
                              if (externalOnChange) {
                                externalOnChange(
                                  newSelectedOptions,
                                  { option },
                                  null
                                );
                              }
                              handleDropdownClose({
                                externalOnDropdownClose,
                                setCurrentOptions,
                                initialOptions,
                                currentOptions,
                                setIsOpen,
                                onBlur,
                                event: event,
                              });
                            }
                          } else {
                            // Existing multi-select logic
                            const newSelectedOptions = Array.isArray(
                              selectedOptions
                            )
                              ? [...selectedOptions]
                              : [];
                            const parentIndex = newSelectedOptions.findIndex(
                              (sel) => sel.value === submenuParent.value
                            );

                            if (isChildSelected) {
                              if (parentIndex !== -1) {
                                const parent = newSelectedOptions[parentIndex];
                                parent.children = parent.children.filter(
                                  (child) => child.value !== option.value
                                );
                                if (parent.children.length === 0) {
                                  newSelectedOptions.splice(parentIndex, 1);
                                }
                              }
                            } else {
                              if (parentIndex !== -1) {
                                // Parent exists - add child (no limit check needed)
                                const parent = newSelectedOptions[parentIndex];
                                if (
                                  !parent.children.some(
                                    (child) => child.value === option.value
                                  )
                                ) {
                                  parent.children.push(option);
                                }
                              } else {
                                // Parent doesn't exist - check limit before adding new parent
                                if (maxSelectableOptions !== undefined) {
                                  const currentCount =
                                    countTotalSelectedOptions(selectedOptions);
                                  if (currentCount >= maxSelectableOptions) {
                                    return;
                                  }
                                }
                                newSelectedOptions.push({
                                  ...submenuParent,
                                  children: [option],
                                });
                              }
                            }
                            setSelectedOptions(newSelectedOptions);
                            if (externalOnChange) {
                              externalOnChange(
                                newSelectedOptions,
                                { option },
                                null
                              );
                            }
                          }
                        }}
                      >
                        {isMulti || isMultiInSubmenu ? (
                          <Checkbox
                            withoutFormLabel={true}
                            label={
                              <div className="select-label-with-icon">
                                {option.label}
                              </div>
                            }
                            checked={isChildSelected || false}
                            onChange={() => null}
                            disabled={shouldDisableSubmenuOption}
                          />
                        ) : (
                          <div className="select-label-with-icon">
                            {option.label}
                          </div>
                        )}
                      </div>
                    );
                  })}
                </div>
              </div>
            )}
          </div>
        </Dropdown>
      </div>
      <Toast
        isOpen={openToast}
        message={toastMessage}
        onClose={() => setOpenToast(!openToast)}
        position="top-right"
        variant="error"
      />
    </div>
  );
});
