import MUIMenu from "@mui/material/Menu";
import React, { forwardRef, useState } from "react";

import { nestedMenuItemsFromObject } from "./nestedMenuItemsFromObject";
import { Button } from "../Button";
import "./Menu.styles.scss";

export const Menu = forwardRef(function Menu(props, ref) {
  const {
    options: data,
    onClick = () => {},
    ButtonProps,
    MenuProps,
    onClose,
    iconPlacement = "left",
    withCheckbox = false,
    withActionButtons = false,
    onPrimaryButtonClick = () => {},
    onTertiaryButtonClick = () => {},
    withSection,
    anchorEl,
    open,
    selected,
    // Custom header support
    renderCustomHeader,
    customHeaderProps = {},
    filteredOptions,
    searchQuery,
    onSearchChange,
    onSelectAll,
    onClearSelection,
    primaryButtonProps = {},
    tertiaryButtonProps = {},
    tertiaryButtonLabel,
    menuContainerClassName,
    ...rest
  } = props;

  const [selectedItems, setSelectedItems] = useState([]);

  // Sync internal selectedItems with external selectedItems when provided
  React.useEffect(() => {
    if (Array.isArray(selected)) {
      setSelectedItems(selected);
    } else if (customHeaderProps.selectedItems) {
      setSelectedItems(customHeaderProps.selectedItems);
    }
  }, [selected, customHeaderProps.selectedItems]);

  const handleClose = () => {
    if (onClose) {
      onClose();
    }
  };

  const handleSelect = (opt, event) => {
    const newSelectedItems = selectedItems.includes(opt.value)
      ? selectedItems.filter((item) => item !== opt.value)
      : [...selectedItems, opt.value];

    setSelectedItems(newSelectedItems);

    if (customHeaderProps.onSelectionChange) {
      customHeaderProps.onSelectionChange(newSelectedItems);
    }

    // call item-level handler only if it's a function
    let itemResult;
    if (typeof opt?.onClick === "function") {
      try {
        itemResult = opt.onClick(opt, event);
      } catch (e) {
        console.warn("item onClick threw:", e);
      }
    }

    // call menu-level onClick only if it's a function
    if (typeof onClick === "function") {
      try {
        onClick(opt, newSelectedItems, itemResult);
      } catch (e) {
        console.warn("Menu onClick threw:", e);
      }
    }
  };

  const handleSelectAll = () => {
    const allValues = (filteredOptions || data || []).map((opt) => opt.value);
    console.log("allValues", allValues);
    setSelectedItems(allValues);
    if (onSelectAll) {
      onSelectAll(allValues);
    }
  };

  const handleClearSelection = () => {
    setSelectedItems([]);
    if (onClearSelection) {
      onClearSelection();
    }
  };

  const handleSearchChange = (value) => {
    if (onSearchChange) {
      onSearchChange(value);
    }
  };

  // Check for loading/empty states
  const isLoading = customHeaderProps.isLoading;
  const isSearching = customHeaderProps.isSearching;
  const hasEmptySearch = searchQuery && data?.length === 0 && !isSearching;
  const hasNoInitialData = !searchQuery && data?.length === 0 && !isLoading;

  const renderLoadingState = () => (
    <div style={{ padding: "16px", textAlign: "center", color: "#666" }}>
      <div> Loading options...</div>
    </div>
  );

  const renderSearchingState = () => (
    <div style={{ padding: "16px", textAlign: "center", color: "#666" }}>
      <div> Searching...</div>
    </div>
  );

  const renderEmptySearchState = () => (
    <div style={{ padding: "16px", textAlign: "center", color: "#666" }}>
      <div> No results found for "{searchQuery}"</div>
    </div>
  );

  const renderNoDataState = () => (
    <div style={{ padding: "16px", textAlign: "center", color: "#666" }}>
      <div>📭 No options available</div>
    </div>
  );

  const menuItems = nestedMenuItemsFromObject({
    handleClose: onClose,
    isOpen: open,
    menuItemsData: data ?? [],
    withCheckbox,
    handleSelect,
    selectedItems,
    selected,
    ...rest,
  });

  // Render custom header if provided
  const renderHeader = () => {
    if (renderCustomHeader) {
      return renderCustomHeader({
        options: filteredOptions || data || [],
        selectedItems,
        searchQuery,
        onSearchChange: handleSearchChange,
        onSelectAll: handleSelectAll,
        onClearSelection: handleClearSelection,
        ...customHeaderProps,
      });
    }
    return null;
  };

  // Configure positioning based on iconPlacement
  const getMenuPositioning = () => {
    if (iconPlacement === "top") {
      return {
        anchorOrigin: {
          vertical: "top",
          horizontal: "center",
        },
        transformOrigin: {
          vertical: "bottom",
          horizontal: "center",
        },
      };
    }
    // Default positioning (bottom)
    return {
      anchorOrigin: {
        vertical: "bottom",
        horizontal: "center",
      },
      transformOrigin: {
        vertical: "top",
        horizontal: "center",
      },
    };
  };

  const menuPositioning = getMenuPositioning();

  return (
    <div ref={ref} {...rest} style={{ display: "none" }}>
      {/* hiding this parent div as it is taking extra space */}
      <MUIMenu
        id="basic-menu"
        className={`ia-styles ia-menu ${menuContainerClassName}`}
        anchorEl={anchorEl}
        open={open}
        onClose={handleClose}
        // anchorOrigin={MenuProps?.anchorOrigin || menuPositioning.anchorOrigin}
        {...MenuProps}
      >
        {renderHeader()}

        {/* Show appropriate content based on loading/data state */}
        {isLoading ? (
          renderLoadingState()
        ) : isSearching ? (
          renderSearchingState()
        ) : hasEmptySearch ? (
          renderEmptySearchState()
        ) : hasNoInitialData ? (
          renderNoDataState()
        ) : (
          <div className="menu-scroll-area">{menuItems}</div>
        )}

        {withActionButtons &&
          withCheckbox &&
          !isLoading &&
          !isSearching &&
          data?.length > 0 && (
            <div className="bottom_action">
              <div className="ia-menu-action-button-container">
                {tertiaryButtonLabel && (
                  <Button
                    variant="tertiary"
                    onClick={onTertiaryButtonClick}
                    {...tertiaryButtonProps}
                  >
                    {tertiaryButtonLabel || "Cancel"}
                  </Button>
                )}
                <Button
                  variant="primary"
                  onClick={onPrimaryButtonClick}
                  disabled={primaryButtonProps?.disabled}
                  {...primaryButtonProps}
                >
                  {primaryButtonProps?.loading
                    ? "Loading..."
                    : primaryButtonProps?.label || "Apply"}
                </Button>
              </div>
            </div>
          )}
      </MUIMenu>
    </div>
  );
});
