import React, { ReactNode, useEffect, useRef, useState } from "react";
import MenuButton from "./MenuButton/MenuButton";
import { MenuItemProps } from "./MenuItem/MenuItem";
import MenuList from "./MenuList/MenuList";
import StyledMenu from "./StyledMenu";

export type horizontal = "left" | "center" | "right";
export type vertical = "bottom" | "center" | "top";

type classes = {
  menu?: string;
  button?: string;
  list?: string;
  item?: string;
};

export type PositionProps = {
  horizontal: horizontal;
  vertical: vertical;
  horizontalOffset?: number;
  verticalOffset?: number;
};

type menuRefType = HTMLDivElement | null;

type MenuProps = PositionProps & {
  classes?: classes;
  menuButton: ReactNode | string;
  menuItems: MenuItemProps[];
  props?: any;
};

const Menu: React.FC<MenuProps> = ({
  classes,
  menuButton,
  menuItems,
  horizontal = "left",
  vertical = "bottom",
  horizontalOffset,
  verticalOffset,
  ...props
}) => {
  const [showMenu, setShowMenu] = useState(false);
  const menuRef = useRef<menuRefType>(null);

  const toggleMenu = () => {
    setShowMenu((show) => !show);
  };

  const closeMenu = (event: MouseEvent) => {
    const menu: menuRefType = menuRef.current;
    if (
      menu &&
      event.target instanceof Node &&
      !(event.target === menu || menu.contains(event.target))
    )
      setShowMenu(false);
  };

  useEffect(() => {
    document.addEventListener("click", closeMenu);

    return () => {
      document.removeEventListener("click", closeMenu);
    };
  }, []);

  return (
    <StyledMenu className={classes?.menu} ref={menuRef} {...props}>
      <MenuButton className={classes?.button} toggleMenu={toggleMenu}>
        {menuButton}
      </MenuButton>
      <MenuList
        className={classes?.list}
        itemClassName={classes?.item}
        items={menuItems}
        showMenu={showMenu}
        horizontal={horizontal}
        horizontalOffset={horizontalOffset}
        vertical={vertical}
        verticalOffset={verticalOffset}
      />
    </StyledMenu>
  );
};

export default Menu;
