import React, { useState, useRef, isValidElement } from 'react';
import { ExpandMore } from '@mui/icons-material';
import {
  Popper,
  Paper,
  ClickAwayListener,
  MenuList,
  MenuItem,
  MenuItemProps,
  ButtonGroup,
  ButtonGroupProps,
  Button,
  ButtonProps,
} from '@mui/material';
import noop from 'lodash/noop';

import { styled } from '../Theme';

export interface SplitButtonProps extends Omit<ButtonGroupProps, 'children'> {
  menu?:
    | React.ReactElement<MenuItemProps, typeof MenuItem>
    | React.ReactElement<MenuItemProps, typeof MenuItem>[]
    | MenuItemProps[];
  children?: React.ReactNode | (() => React.ReactNode);
  onClick?: () => void;
  menuButtonProps?: ButtonProps;
}

export default function SplitButton({ ...props }: SplitButtonProps) {
  const {
    size = 'medium',
    color = 'primary',
    menu = [],
    children = null,
    variant = 'contained',
    onClick = noop,
    menuButtonProps = {},
    ...rest
  } = props;

  const [open, setOpen] = useState(false);
  const anchorRef = useRef<HTMLDivElement | null>(null);
  const menuItems = Array.isArray(menu)
    ? // eslint-disable-next-line react/no-array-index-key
      menu.map((item, index) => (isValidElement(item) ? item : <MenuItem {...item} key={index} />))
    : menu;

  const onToggle = () => {
    setOpen((prevOpen) => !prevOpen);
  };

  const handleClose = (e: MouseEvent | TouchEvent) => {
    if (anchorRef.current && anchorRef.current.contains(e.target as HTMLElement)) {
      return;
    }
    setOpen(false);
  };

  // 点击 item 后收起下拉菜单, 如果想要点击 action 后不收起下拉菜单, 可以在 item#onClick 时调用 e.stopPropagation()
  const handleItemClick: React.MouseEventHandler<HTMLUListElement> = (e) => {
    if ((e.target as HTMLElement).closest('.MuiMenuItem-root')) {
      setOpen(false);
    }
  };

  return (
    <>
      <StyledButtonGroup variant={variant} size={size} color={color} ref={anchorRef} {...rest}>
        {typeof children === 'function' ? (
          children()
        ) : (
          <Button onClick={onClick} color={color}>
            {children}
          </Button>
        )}
        <Button onClick={onToggle} color={color} {...menuButtonProps} aria-label="more functions">
          <ExpandMore />
        </Button>
      </StyledButtonGroup>
      <StyledPopper open={open} anchorEl={anchorRef.current} placement="bottom-end" disablePortal={false}>
        <Paper>
          <ClickAwayListener onClickAway={handleClose}>
            <MenuList onClick={handleItemClick}>{menuItems}</MenuList>
          </ClickAwayListener>
        </Paper>
      </StyledPopper>
    </>
  );
}

SplitButton.Item = MenuItem;

const StyledButtonGroup = styled(ButtonGroup)`
  > .MuiButtonBase-root:last-of-type {
    min-width: 2em;
    padding-left: 0;
    padding-right: 0;
  }
`;

const StyledPopper = styled(Popper)`
  z-index: ${(props) => props.theme.zIndex.tooltip};
  .MuiList-root {
    padding: 4px 0;
  }
  .MuiListItem-root {
    padding-top: 4px;
    padding-bottom: 4px;
  }
`;
