import { mergeProps, Show, splitProps, useContext } from "solid-js";
import classNames from "./classnames";
import { useDropdownMenu } from "solid-bootstrap-core";
import DropdownContext from "./DropdownContext";
import InputGroupContext from "./InputGroupContext";
import NavbarContext from "./NavbarContext";
import { useBootstrapPrefix } from "./ThemeProvider";
import { Dynamic } from "solid-js/web";
const defaultProps = {
    as: "div",
    flip: true,
};
export function getDropdownMenuPlacement(alignEnd, dropDirection, isRTL) {
    const topStart = isRTL ? "top-end" : "top-start";
    const topEnd = isRTL ? "top-start" : "top-end";
    const bottomStart = isRTL ? "bottom-end" : "bottom-start";
    const bottomEnd = isRTL ? "bottom-start" : "bottom-end";
    const leftStart = isRTL ? "right-start" : "left-start";
    const leftEnd = isRTL ? "right-end" : "left-end";
    const rightStart = isRTL ? "left-start" : "right-start";
    const rightEnd = isRTL ? "left-end" : "right-end";
    let placement = alignEnd ? bottomEnd : bottomStart;
    if (dropDirection === "up")
        placement = alignEnd ? topEnd : topStart;
    else if (dropDirection === "end")
        placement = alignEnd ? rightEnd : rightStart;
    else if (dropDirection === "start")
        placement = alignEnd ? leftEnd : leftStart;
    return placement;
}
const DropdownMenu = (p) => {
    const [local, props] = splitProps(mergeProps(defaultProps, p), [
        "as",
        "bsPrefix",
        "className",
        "align",
        "rootCloseEvent",
        "flip",
        "show",
        "renderOnMount",
        "popperConfig",
        "ref",
        "variant",
    ]);
    let alignEnd = false;
    const isNavbar = useContext(NavbarContext);
    const prefix = useBootstrapPrefix(local.bsPrefix, "dropdown-menu");
    const dropdownContext = useContext(DropdownContext);
    const align = local.align || dropdownContext.align;
    const isInputGroup = useContext(InputGroupContext);
    const alignClasses = [];
    if (align) {
        if (typeof align === "object") {
            const keys = Object.keys(align);
            if (keys.length) {
                const brkPoint = keys[0];
                // @ts-ignore
                const direction = align[brkPoint];
                // .dropdown-menu-end is required for responsively aligning
                // left in addition to align left classes.
                alignEnd = direction === "start";
                alignClasses.push(`${prefix}-${brkPoint}-${direction}`);
            }
        }
        else if (align === "end") {
            alignEnd = true;
        }
    }
    const [menuProps, menuMeta] = useDropdownMenu({
        get flip() {
            return local.flip;
        },
        get rootCloseEvent() {
            return local.rootCloseEvent;
        },
        get show() {
            return local.show;
        },
        get usePopper() {
            return !isNavbar && alignClasses.length === 0;
        },
        get offset() {
            return [0, 2];
        },
        get popperConfig() {
            return local.popperConfig;
        },
        get placement() {
            return getDropdownMenuPlacement(alignEnd, dropdownContext.drop, dropdownContext.isRTL);
        },
    });
    const mergedRef = (ref) => {
        menuProps.ref?.(ref);
        local.ref?.(ref);
    };
    // createEffect(() => {
    //   // Popper's initial position for the menu is incorrect when
    //   // renderOnMount=true. Need to call update() to correct it.
    //   if (menuMeta.show) menuMeta.popper?.update();
    // });
    const extendedMenuProps = mergeProps(menuProps, 
    // For custom components provide additional, non-DOM, props;
    typeof local.as !== "string"
        ? {
            get show() {
                return menuMeta.show;
            },
            get close() {
                return () => menuMeta.toggle?.(false);
            },
            get align() {
                return align;
            },
        }
        : {});
    // we don't need the default popper style,
    // menus are display: none when not shown.
    const style = () => menuMeta.popper?.placement
        ? { ...props.style, ...menuProps.style }
        : props.style;
    return (<Show when={menuMeta.hasShown || local.renderOnMount || isInputGroup}>
      <Dynamic component={local.as} {...props} {...extendedMenuProps} ref={mergedRef} style={style()} {...(alignClasses.length || isNavbar
        ? {
            "data-bs-popper": "static",
        }
        : {})} className={classNames(local.className, prefix, menuMeta.show && "show", alignEnd && `${prefix}-end`, local.variant && `${prefix}-${local.variant}`, ...alignClasses)}>
        {props.children}
      </Dynamic>
    </Show>);
};
export default DropdownMenu;
