/**
 * TEAM: frontend_infra
 * @flow
 */

import * as React from "react";
import {StyleSheet, css, type SheetEntry} from "aphrodite";
// TODO: Fix this eslint issue on next edit. This is an autogenerated comment.
// eslint-disable-next-line flexport/no-legacy-dependencies
import deprecatedZIndices from "latitude/tools/deprecatedZIndices";
import typeof Button from "./button/Button";
import typeof IconButton from "./button/IconButton";
import typeof ToggleButton from "./base_candidate/button/ToggleButton";
import PopupWithClickAway from "./popup/PopupWithClickAway";
import colors from "./colors";
import {border, include, margin} from "./styles/index";
import StackingContext from "./StackingContext";

type SetPopupVisible = (isVisible: boolean) => void;
type Props = {|
  // Makes the field unclickable and greyed out.
  +disabled?: boolean,
  // The button that triggers the dropdown menu.
  +button: React.Element<Button | IconButton | ToggleButton>,
  // The content of the button to render, {children} || func that gets called w/ setPopupVisible
  +children: React.Node | (SetPopupVisible => React.Node),
  // Overrides the default container of the dropdown to have custom sizing, colors, etc.
  +isCustomContainer?: boolean,
  // Aligns the right part of the menu with the right border of the button; by default, it is left-left.
  +menuAlignRight?: boolean,
|};

/**
 * @short Use DropdownButton for most cases, this is still a button that launches a dropdown, but allows for custom {children} to be passed in.
 * @status Stable
 * @category Interaction
 *
 * Use for a dropdown with custom rendering, could also use anytime you need to show/hide something relative to a parent onClick
 * props.children - will render as {children} or {children(setPopupVisible)} else if you need to toggle popup from children
 */
export default function CustomDropdownButton(props: Props): React.Node {
  const {button, children, disabled, isCustomContainer, menuAlignRight} = props;
  function child(togglePopup: function, isOpen: boolean): React.Node {
    // create setPopupVisible for legacy to use (not built into newer PopupWithClickAway)
    const setPopupVisible = (open: boolean) => {
      if (isOpen !== open) togglePopup();
    };
    const processedChildren =
      typeof children === "function" ? children(setPopupVisible) : children;
    return isCustomContainer ? (
      processedChildren
    ) : (
      <div className={css(styles.dropdownContainer)}>{processedChildren}</div>
    );
  }
  const {isDeprecatedZIndexEnabled} = React.useContext(StackingContext);

  return (
    <PopupWithClickAway>
      {(Target, Popup, {isOpen, togglePopup}) => (
        <div className={css(styles.outerDiv)}>
          <Target>
            {React.cloneElement(button, {
              disabled,
              onClick: e => {
                if (disabled) return;
                if (button.props.onClick) {
                  button.props.onClick(e);
                }
                togglePopup();
                e.stopPropagation();
              },
            })}
          </Target>
          {!disabled && (
            <Popup
              placement={menuAlignRight ? "bottom-end" : "bottom-start"}
              zIndex={
                isDeprecatedZIndexEnabled
                  ? deprecatedZIndices.zIndex1500AboveModal.zIndex
                  : null
              }
            >
              {child(togglePopup, isOpen)}
            </Popup>
          )}
        </div>
      )}
    </PopupWithClickAway>
  );
}

export const styles: {|
  dropdownContainer: SheetEntry,
  outerDiv: SheetEntry,
|} = StyleSheet.create({
  dropdownContainer: {
    ...include(margin.t.xs),
    backgroundColor: colors.white,
    maxHeight: 250,
    width: 400,
    overflowY: "auto",
    ...border.a.s,
    borderRadius: 3,
    boxShadow: "2px 2px 2px rgba(0,0,0,0.06)",
  },
  outerDiv: {
    display: "inline-block",
  },
});

export const _test = {
  CustomDropdownButton,
};
