import React, { memo, useCallback, useMemo } from 'react';
import Menu from '@mui/material/Menu';
import type { MenuProps } from '@mui/material/Menu';
import clsx from 'clsx';
import { useToggle } from 'react-use';
import createClasses from './styles';
import type { DropDownMenuProps, MenuContentProps } from './types';
import ListItems from './ListItems';
import MenuContent from './MenuContent';
import MenuItem from './MenuItem';

const DropdownMenu = (props: DropDownMenuProps) => {
  const {
    onClose,
    anchorEl,
    anchorElTopAddition,
    disablePortal,
    open,
    search,
    handleSearchChangeCallback,
    arrowSide = 'topLeft',
    leftAddition = 12,
    searchHighlight,
    searchPlaceholder = 'Search',
    showSelectedIcon,
    width = 200,
    classes,
    ...menuProps
  } = props;

  const boundingClientRect = useMemo(
    () => (anchorEl as HTMLElement)?.getBoundingClientRect(),
    [anchorEl]
  );

  const [showSort, toggleShowSort] = useToggle(true);
  const handleTextChange: MenuContentProps['handleTextChange'] = useCallback(
    e => {
      toggleShowSort(
        (typeof e === 'string' ? e?.length : (e?.target as HTMLInputElement)?.value?.length) === 0
      );

      handleSearchChangeCallback?.(
        typeof e === 'string' ? e : (e?.target as HTMLInputElement)?.value
      );
    },
    [handleSearchChangeCallback, toggleShowSort]
  );

  const handleClose: MenuProps['onClose'] = useCallback(
    (e, r) => {
      onClose?.(e, r);
      handleTextChange('');
    },
    [handleTextChange, onClose]
  );

  const styles = createClasses({
    arrowSide,
    search,
    showSort,
    width
  });
  return (
    <Menu
      data-testid="dropdownMenu"
      disablePortal={disablePortal}
      classes={{
        paper: clsx(styles.menuRoot, classes?.menuRoot, {
          [styles.searchField]: search
        }),
        list: styles.menuListWrapper
      }}
      anchorEl={anchorEl as Element}
      open={!!anchorEl}
      onClose={handleClose}
      transformOrigin={
        menuProps.transformOrigin || {
          vertical: 'top',
          horizontal: 'left'
        }
      }
      MenuListProps={{
        // eslint-disable-next-line
        // @ts-ignore
        component: 'div'
      }}
      PaperProps={{
        style: {
          transform: `translate(${
            (boundingClientRect?.width / 2 || 0) + leftAddition
          }px ,${anchorElTopAddition}px)`
        }
      }}
    >
      <MenuContent
        {...menuProps}
        styles={styles}
        classes={classes}
        search={search}
        searchHighlight={searchHighlight}
        searchPlaceholder={searchPlaceholder}
        showSelectedIcon={showSelectedIcon}
        showSort={showSort}
        handleTextChange={handleTextChange}
      />
    </Menu>
  );
};

const m = memo(DropdownMenu);
export { m as DropdownMenu, ListItems, MenuContent, MenuItem };
