"use client";

/* eslint-disable react/no-children-prop, react-x/no-children-for-each, react-x/no-children-map, react-x/no-children-to-array, react-x/no-clone-element, sonarjs/function-return-type, sonarjs/no-identical-functions, sonarjs/no-unused-vars, max-lines, unicorn/no-array-callback-reference, unicorn/no-useless-undefined, unicorn/prefer-at, unicorn/prefer-dom-node-dataset, jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */

import {Drawer as BaseDrawer} from "@base-ui/react/drawer";
import {Menu as BaseMenu} from "@base-ui/react/menu";
import {mergeProps} from "@base-ui/react/merge-props";
import {useRender} from "@base-ui/react/use-render";
import {ChevronLeftIcon, ChevronRightIcon} from "lucide-react";
import {AnimatePresence, motion, type Transition} from "motion/react";
import * as React from "react";

import {useIsMobile} from "@/hooks/useIsMobile";
import {cn} from "@/lib/utilities";
import styles from "./dropdrawer.module.css";

const MOBILE_MENU_TITLE = "Menu";
const MOBILE_SUBMENU_TITLE = "Submenu";
const MOBILE_BACK_LABEL = "Go back";

interface DropDrawerContextValue {
  isMobile: boolean;
}

const DropDrawerContext = React.createContext<DropDrawerContextValue | null>(null);

const useDropDrawerContext = (): DropDrawerContextValue => {
  const context = React.useContext(DropDrawerContext);

  if (context === null) {
    throw new Error("DropDrawer components cannot be rendered outside the Context");
  }

  return context;
};

const Drawer = BaseDrawer.Root;
const DrawerPortal = BaseDrawer.Portal;

const DrawerTrigger = React.forwardRef<HTMLButtonElement, React.ComponentPropsWithRef<typeof BaseDrawer.Trigger> & {asChild?: boolean}>(
  (props, forwardedRef) => {
    const {asChild = false, children, className, render, ...otherProps} = props;
    const renderProp = asChild && React.isValidElement(children) ? children : render;

    return (
      <BaseDrawer.Trigger
        {...otherProps}
        ref={forwardedRef}
        render={useRender({
          defaultTagName: "button",
          render: renderProp as never,
          props: mergeProps({className}, {}),
        })}>
        {renderProp ? undefined : children}
      </BaseDrawer.Trigger>
    );
  },
);
DrawerTrigger.displayName = "DrawerTrigger";

function DrawerOverlay(props: Readonly<React.ComponentPropsWithRef<typeof BaseDrawer.Backdrop>>): React.ReactElement {
  const {className, render, ...otherProps} = props;

  return (
    <BaseDrawer.Backdrop
      {...otherProps}
      render={useRender({
        defaultTagName: "div",
        render: render as never,
        props: mergeProps({className: cn(styles.drawerOverlay, className)}, {}),
      })}
    />
  );
}

const DrawerContent = React.forwardRef<HTMLDivElement, React.ComponentPropsWithRef<typeof BaseDrawer.Popup> & {children?: React.ReactNode}>(
  (props, forwardedRef) => {
    const {className, children, render, ...otherProps} = props;

    return (
      <DrawerPortal>
        <DrawerOverlay />
        <BaseDrawer.Viewport className={styles.drawerViewport}>
          <BaseDrawer.Popup
            {...otherProps}
            ref={forwardedRef}
            render={useRender({
              defaultTagName: "div",
              render: render as never,
              props: mergeProps({className: cn(styles.drawerContent, className)}, {}),
            })}>
            <div className={styles.drawerHandle} />
            <BaseDrawer.Content className={styles.drawerInnerContent}>{children}</BaseDrawer.Content>
          </BaseDrawer.Popup>
        </BaseDrawer.Viewport>
      </DrawerPortal>
    );
  },
);
DrawerContent.displayName = "DrawerContent";

function DrawerHeader(
  props: Readonly<React.ComponentPropsWithRef<"div"> & {render?: useRender.RenderProp<Record<string, never>>}>,
): React.ReactElement {
  const {className, children, render, ...otherProps} = props;

  return useRender({
    defaultTagName: "div",
    render: render as never,
    props: mergeProps({className: cn(styles.drawerHeader, className)}, otherProps, {children}),
  });
}

function DrawerFooter(
  props: Readonly<React.ComponentPropsWithRef<"div"> & {render?: useRender.RenderProp<Record<string, never>>}>,
): React.ReactElement {
  const {className, children, render, ...otherProps} = props;

  return useRender({
    defaultTagName: "div",
    render: render as never,
    props: mergeProps({className: cn(styles.drawerFooter, className)}, otherProps, {children}),
  });
}

function DrawerTitle(props: Readonly<React.ComponentPropsWithRef<typeof BaseDrawer.Title>>): React.ReactElement {
  const {className, children, render, ...otherProps} = props;

  return (
    <BaseDrawer.Title
      {...otherProps}
      render={useRender({
        defaultTagName: "h2",
        render: render as never,
        props: mergeProps({className: cn(styles.drawerTitle, className)}, {}),
      })}>
      {children}
    </BaseDrawer.Title>
  );
}

const DropdownMenu = BaseMenu.Root;
const DropdownMenuSub = BaseMenu.SubmenuRoot;

const DropdownMenuTrigger = React.forwardRef<HTMLButtonElement, React.ComponentPropsWithRef<typeof BaseMenu.Trigger> & {asChild?: boolean}>(
  (props, forwardedRef) => {
    const {asChild = false, children, className, render, ...otherProps} = props;
    const renderProp = asChild && React.isValidElement(children) ? children : render;

    return (
      <BaseMenu.Trigger
        {...otherProps}
        ref={forwardedRef}
        render={useRender({
          defaultTagName: "button",
          render: renderProp as never,
          props: mergeProps({className}, {}),
        })}>
        {renderProp ? undefined : children}
      </BaseMenu.Trigger>
    );
  },
);
DropdownMenuTrigger.displayName = "DropdownMenuTrigger";

const DropdownMenuContent = React.forwardRef<
  HTMLDivElement,
  React.ComponentPropsWithRef<typeof BaseMenu.Positioner> & {children?: React.ReactNode}
>((props, forwardedRef) => {
  const {className, children, render, ...otherProps} = props;

  return (
    <BaseMenu.Portal>
      <BaseMenu.Positioner
        {...otherProps}
        ref={forwardedRef}
        render={useRender({
          defaultTagName: "div",
          props: mergeProps({className: styles.dropdownPositioner}, {}),
        })}>
        <BaseMenu.Popup
          render={useRender({
            defaultTagName: "div",
            render: render as never,
            props: mergeProps({className: cn(styles.dropdownContent, className)}, {}),
          })}>
          {children}
        </BaseMenu.Popup>
      </BaseMenu.Positioner>
    </BaseMenu.Portal>
  );
});
DropdownMenuContent.displayName = "DropdownMenuContent";

interface DropdownMenuItemProps extends React.ComponentPropsWithRef<typeof BaseMenu.Item> {
  /** @deprecated Prefer Base UI's `render` prop. */
  asChild?: boolean;
  /**
   * Whether to apply inset spacing to align with grouped menu content.
   * @default false
   */
  inset?: boolean;
}

function DropdownMenuItem(props: Readonly<DropdownMenuItemProps>): React.ReactElement {
  // eslint-disable-next-line sonarjs/deprecation -- backward-compatible asChild API
  const {asChild = false, children, className, inset = false, render, ...otherProps} = props;
  const renderProp = asChild && React.isValidElement(children) ? children : render;

  return (
    <BaseMenu.Item
      {...otherProps}
      render={useRender({
        defaultTagName: "div",
        render: renderProp as never,
        props: mergeProps({className: cn(styles.desktopItem, inset && styles.inset, className)}, {}),
      })}>
      {renderProp ? undefined : children}
    </BaseMenu.Item>
  );
}

function DropdownMenuLabel(props: Readonly<React.ComponentPropsWithRef<typeof BaseMenu.GroupLabel>>): React.ReactElement {
  const {className, children, render, ...otherProps} = props;

  return (
    <BaseMenu.GroupLabel
      {...otherProps}
      render={useRender({
        defaultTagName: "div",
        render: render as never,
        props: mergeProps({className: cn(styles.desktopLabel, className)}, {}),
      })}>
      {children}
    </BaseMenu.GroupLabel>
  );
}

function DropdownMenuSeparator(props: Readonly<React.ComponentPropsWithRef<typeof BaseMenu.Separator>>): React.ReactElement {
  const {className, render, ...otherProps} = props;

  return (
    <BaseMenu.Separator
      {...otherProps}
      render={useRender({
        defaultTagName: "div",
        render: render as never,
        props: mergeProps({className: cn(styles.desktopSeparator, className)}, {}),
      })}
    />
  );
}

function DropdownMenuSubTrigger(
  props: Readonly<React.ComponentPropsWithRef<typeof BaseMenu.SubmenuTrigger> & {inset?: boolean}>,
): React.ReactElement {
  const {className, children, inset = false, render, ...otherProps} = props;

  return (
    <BaseMenu.SubmenuTrigger
      {...otherProps}
      render={useRender({
        defaultTagName: "div",
        render: render as never,
        props: mergeProps({className: cn(styles.desktopSubTrigger, inset && styles.inset, className)}, {}),
      })}>
      {children}
      <ChevronRightIcon className={styles.chevron} />
    </BaseMenu.SubmenuTrigger>
  );
}

function DropdownMenuSubContent(
  props: Readonly<React.ComponentPropsWithRef<typeof BaseMenu.Positioner> & {children?: React.ReactNode}>,
): React.ReactElement {
  const {className, children, render, ...otherProps} = props;

  return (
    <BaseMenu.Positioner
      {...otherProps}
      render={useRender({
        defaultTagName: "div",
        props: mergeProps({className: styles.dropdownPositioner}, {}),
      })}>
      <BaseMenu.Popup
        render={useRender({
          defaultTagName: "div",
          render: render as never,
          props: mergeProps({className: cn(styles.dropdownSubContent, className)}, {}),
        })}>
        {children}
      </BaseMenu.Popup>
    </BaseMenu.Positioner>
  );
}

type DropDrawerRootProps = React.ComponentProps<typeof Drawer> | React.ComponentProps<typeof DropdownMenu>;
type DropDrawerTriggerProps =
  | React.ComponentPropsWithoutRef<typeof DrawerTrigger>
  | React.ComponentPropsWithoutRef<typeof DropdownMenuTrigger>;
type DropDrawerContentProps =
  | React.ComponentPropsWithoutRef<typeof DrawerContent>
  | React.ComponentPropsWithoutRef<typeof DropdownMenuContent>;

interface MobileSubmenuDataAttributes {
  "data-parent-submenu-id"?: string;
  "data-parent-submenu"?: string;
  "data-submenu-id"?: string;
}

interface SharedDropDrawerItemProps
  extends Omit<React.ComponentPropsWithoutRef<typeof BaseMenu.Item>, "children" | "onClick" | "onSelect">, MobileSubmenuDataAttributes {
  /**
   * Item contents.
   * @default undefined
   */
  children?: React.ReactNode;
  /**
   * Additional CSS classes merged with the item styles.
   * @default undefined
   */
  className?: string;
  /**
   * Whether the desktop dropdown should close after the item is activated.
   * @default undefined
   */
  closeOnClick?: boolean;
  /**
   * Optional trailing icon or affordance rendered alongside the item content.
   * @default undefined
   */
  icon?: React.ReactNode;
  /**
   * Whether to apply inset spacing to align the item with grouped content.
   * @default undefined
   */
  inset?: boolean;
  /**
   * Mouse click handler invoked when the item is activated.
   * @default undefined
   */
  onClick?: React.MouseEventHandler<HTMLElement>;
  /**
   * Selection callback invoked with the native event when the item is activated.
   * @default undefined
   */
  onSelect?: (event: Event) => void;
}

interface SubmenuContextType {
  activeSubmenu: string | null;
  navigateToSubmenu?: (id: string, title: string) => void;
  registerSubmenuContent?: (id: string, content: ReadonlyArray<React.ReactNode>) => void;
  setActiveSubmenu: (id: string | null) => void;
  setSubmenuTitle: (title: string | null) => void;
  submenuTitle: string | null;
}

const SubmenuContext = React.createContext<SubmenuContextType>({
  activeSubmenu: null,
  navigateToSubmenu: undefined,
  registerSubmenuContent: undefined,
  setActiveSubmenu: () => undefined,
  setSubmenuTitle: () => undefined,
  submenuTitle: null,
});

/**
 * Provides a responsive dropdown-on-desktop, drawer-on-mobile navigation surface.
 *
 * @remarks
 * - Renders either Base UI `Menu.Root` or `Drawer.Root` depending on viewport size
 * - Built on Base UI Menu and Drawer primitives
 *
 * @example
 * ```tsx
 * <DropDrawer>
 *   <DropDrawerTrigger>Open menu</DropDrawerTrigger>
 *   <DropDrawerContent>
 *     <DropDrawerItem>Profile</DropDrawerItem>
 *   </DropDrawerContent>
 * </DropDrawer>
 * ```
 *
 * @see {@link https://base-ui.com/react/components/menu | Base UI Menu Docs}
 */
function DropDrawer({children, ...props}: DropDrawerRootProps): React.JSX.Element {
  const isMobile = useIsMobile();

  return (
    <DropDrawerContext.Provider value={{isMobile}}>
      {isMobile ? (
        <Drawer
          data-slot='drop-drawer'
          {...(props as React.ComponentProps<typeof Drawer>)}>
          {children}
        </Drawer>
      ) : (
        <DropdownMenu
          data-slot='drop-drawer'
          {...(props as React.ComponentProps<typeof DropdownMenu>)}>
          {children}
        </DropdownMenu>
      )}
    </DropDrawerContext.Provider>
  );
}

/**
 * Renders the control that opens the dropdown or drawer surface.
 *
 * @remarks
 * - Renders either a Base UI menu trigger or drawer trigger
 * - Built on Base UI Menu and Drawer primitives
 *
 * @example
 * ```tsx
 * <DropDrawerTrigger>Open menu</DropDrawerTrigger>
 * ```
 *
 * @see {@link https://base-ui.com/react/components/drawer | Base UI Drawer Docs}
 */
const DropDrawerTrigger = React.forwardRef<HTMLButtonElement, DropDrawerTriggerProps>((
  {className, children, ...props},
  forwardedRef,
) => {
  const {isMobile} = useDropDrawerContext();

  return isMobile ? (
    <DrawerTrigger
      ref={forwardedRef}
      data-slot='drop-drawer-trigger'
      className={className}
      {...(props as React.ComponentProps<typeof DrawerTrigger>)}>
      {children}
    </DrawerTrigger>
  ) : (
    <DropdownMenuTrigger
      ref={forwardedRef}
      data-slot='drop-drawer-trigger'
      className={className}
      {...(props as React.ComponentProps<typeof DropdownMenuTrigger>)}>
      {children}
    </DropdownMenuTrigger>
  );
});

/**
 * Renders the responsive dropdown or drawer content surface.
 *
 * @remarks
 * - Renders a Base UI popup on desktop and drawer content on mobile
 * - Built on Base UI Menu and Drawer primitives with animated mobile submenu navigation
 *
 * @example
 * ```tsx
 * <DropDrawerContent>
 *   <DropDrawerItem>Settings</DropDrawerItem>
 * </DropDrawerContent>
 * ```
 *
 * @see {@link https://base-ui.com/react/components/menu | Base UI Menu Docs}
 */
const DropDrawerContent = React.forwardRef<HTMLDivElement, DropDrawerContentProps>((
  {className, children, ...props},
  forwardedRef,
) => {
  const {isMobile} = useDropDrawerContext();
  const [activeSubmenu, setActiveSubmenu] = React.useState<string | null>(null);
  const [submenuTitle, setSubmenuTitle] = React.useState<string | null>(null);
  const [submenuStack, setSubmenuStack] = React.useState<ReadonlyArray<{id: string; title: string}>>([]);
  const [animationDirection, setAnimationDirection] = React.useState<"forward" | "backward">("forward");
  const submenuContentRef = React.useRef(new Map<string, ReadonlyArray<React.ReactNode>>());

  React.useEffect(() => {
    submenuContentRef.current.clear();
  }, [children]);

  const navigateToSubmenu = React.useCallback((id: string, title: string): void => {
    setAnimationDirection("forward");
    setActiveSubmenu(id);
    setSubmenuTitle(title);
    setSubmenuStack((previousStack) => [...previousStack, {id, title}]);
  }, []);

  const goBack = React.useCallback((): void => {
    setAnimationDirection("backward");

    if (submenuStack.length <= 1) {
      setActiveSubmenu(null);
      setSubmenuTitle(null);
      setSubmenuStack([]);
      return;
    }

    const newStack = [...submenuStack];
    newStack.pop();
    const previousSubmenu = newStack[newStack.length - 1];

    if (!previousSubmenu) {
      setActiveSubmenu(null);
      setSubmenuTitle(null);
      setSubmenuStack([]);
      return;
    }

    setActiveSubmenu(previousSubmenu.id);
    setSubmenuTitle(previousSubmenu.title);
    setSubmenuStack(newStack);
  }, [submenuStack]);

  const registerSubmenuContent = React.useCallback((id: string, content: ReadonlyArray<React.ReactNode>): void => {
    submenuContentRef.current.set(id, content);
  }, []);

  const extractSubmenuContent = React.useCallback((elements: React.ReactNode, targetId: string): ReadonlyArray<React.ReactNode> => {
    const result: Array<React.ReactNode> = [];

    const findSubmenuContent = (node: React.ReactNode): void => {
      if (!React.isValidElement(node)) {
        return;
      }

      const element = node as React.ReactElement<{
        "data-submenu-id"?: string;
        children?: React.ReactNode;
        id?: string;
      }>;

      if (element.type === DropDrawerSub) {
        const elementId = element.props.id;
        const dataSubmenuId = element.props["data-submenu-id"];

        if (elementId === targetId || dataSubmenuId === targetId) {
          if (element.props.children) {
            React.Children.forEach(element.props.children, (child) => {
              if (React.isValidElement(child) && child.type === DropDrawerSubContent) {
                const subContentElement = child as React.ReactElement<{children?: React.ReactNode}>;

                React.Children.forEach(subContentElement.props.children, (contentChild) => {
                  result.push(contentChild);
                });
              }
            });
          }

          return;
        }
      }

      if (element.props.children) {
        React.Children.forEach(element.props.children, findSubmenuContent);
      }
    };

    React.Children.forEach(elements, findSubmenuContent);
    return result;
  }, []);

  const getSubmenuContent = React.useCallback(
    (id: string): ReadonlyArray<React.ReactNode> => {
      const cachedContent = submenuContentRef.current.get(id);

      if (cachedContent && cachedContent.length > 0) {
        return cachedContent;
      }

      const submenuContent = extractSubmenuContent(children, id);

      if (submenuContent.length > 0) {
        submenuContentRef.current.set(id, submenuContent);
      }

      return submenuContent;
    },
    [children, extractSubmenuContent],
  );

  const variants = {
    center: {
      opacity: 1,
      x: 0,
    },
    enter: (direction: "forward" | "backward") => ({
      opacity: 0,
      x: direction === "forward" ? "100%" : "-100%",
    }),
    exit: (direction: "forward" | "backward") => ({
      opacity: 0,
      x: direction === "forward" ? "-100%" : "100%",
    }),
  };

  const transition = {
    duration: 0.3,
    ease: [0.25, 0.1, 0.25, 1],
  } satisfies Transition;

  if (isMobile) {
    return (
      <SubmenuContext.Provider
        value={{
          activeSubmenu,
          navigateToSubmenu,
          registerSubmenuContent,
          setActiveSubmenu: (id) => {
            if (id === null) {
              setActiveSubmenu(null);
              setSubmenuTitle(null);
              setSubmenuStack([]);
            }
          },
          setSubmenuTitle,
          submenuTitle,
        }}>
        <DrawerContent
          ref={forwardedRef}
          data-slot='drop-drawer-content'
          className={cn(styles.mobileContent, className)}
          {...(props as React.ComponentProps<typeof DrawerContent>)}>
          {activeSubmenu ? (
            <>
              <DrawerHeader>
                <div className={styles.mobileHeaderRow}>
                  <button
                    type='button'
                    aria-label={MOBILE_BACK_LABEL}
                    onClick={goBack}
                    className={styles.backButton}>
                    <ChevronLeftIcon className={styles.chevron} />
                  </button>
                  <DrawerTitle>{submenuTitle || MOBILE_SUBMENU_TITLE}</DrawerTitle>
                </div>
              </DrawerHeader>
              <div className={styles.mobileViewport}>
                <AnimatePresence
                  initial={false}
                  mode='wait'
                  custom={animationDirection}>
                  <motion.div
                    key={activeSubmenu}
                    custom={animationDirection}
                    variants={variants}
                    initial='enter'
                    animate='center'
                    exit='exit'
                    transition={transition}
                    className={styles.mobileMotionPanel}>
                    {getSubmenuContent(activeSubmenu)}
                  </motion.div>
                </AnimatePresence>
              </div>
            </>
          ) : (
            <>
              <DrawerHeader className={styles.screenReaderOnlyHeader}>
                <DrawerTitle>{MOBILE_MENU_TITLE}</DrawerTitle>
              </DrawerHeader>
              <div className={styles.mobileMainViewport}>
                <AnimatePresence
                  initial={false}
                  mode='wait'
                  custom={animationDirection}>
                  <motion.div
                    key='main-menu'
                    custom={animationDirection}
                    variants={variants}
                    initial='enter'
                    animate='center'
                    exit='exit'
                    transition={transition}
                    className={styles.mobileMotionPanel}>
                    {children}
                  </motion.div>
                </AnimatePresence>
              </div>
            </>
          )}
        </DrawerContent>
      </SubmenuContext.Provider>
    );
  }

  return (
    <SubmenuContext.Provider
      value={{
        activeSubmenu,
        registerSubmenuContent,
        setActiveSubmenu,
        setSubmenuTitle,
        submenuTitle,
      }}>
      <DropdownMenuContent
        ref={forwardedRef}
        data-slot='drop-drawer-content'
        align='end'
        sideOffset={4}
        className={cn(styles.desktopContent, className)}
        {...(props as React.ComponentProps<typeof DropdownMenuContent>)}>
        {children}
      </DropdownMenuContent>
    </SubmenuContext.Provider>
  );
});

/**
 * Renders an actionable item inside the drop drawer surface.
 *
 * @remarks
 * - Renders a Base UI menu item on desktop and a keyboard-accessible `<div>` on mobile
 * - Built on Base UI Menu and Drawer close primitives
 *
 * @example
 * ```tsx
 * <DropDrawerItem icon={<ChevronRightIcon />}>Account</DropDrawerItem>
 * ```
 *
 * @see {@link https://base-ui.com/react/components/menu | Base UI Menu Docs}
 */
function DropDrawerItem({
  className,
  children,
  closeOnClick,
  disabled,
  icon,
  inset,
  onClick,
  onSelect,
  ...props
}: SharedDropDrawerItemProps): React.JSX.Element {
  const {isMobile} = useDropDrawerContext();

  const isInGroup = React.useCallback((element: HTMLElement | null): boolean => {
    if (!element) {
      return false;
    }

    let parent = element.parentElement;

    while (parent) {
      if (parent.hasAttribute("data-drop-drawer-group")) {
        return true;
      }

      parent = parent.parentElement;
    }

    return false;
  }, []);

  const itemRef = React.useRef<HTMLDivElement>(null);
  const [isInsideGroup, setIsInsideGroup] = React.useState(false);

  React.useEffect(() => {
    if (!isMobile) {
      return;
    }

    const timer = globalThis.window.setTimeout(() => {
      if (itemRef.current) {
        setIsInsideGroup(isInGroup(itemRef.current));
      }
    }, 0);

    return () => globalThis.window.clearTimeout(timer);
  }, [isInGroup, isMobile]);

  const handleSelect = React.useCallback(
    (event: Event): void => {
      if (!disabled) {
        onSelect?.(event);
      }
    },
    [disabled, onSelect],
  );

  if (isMobile) {
    const handleClick: React.MouseEventHandler<HTMLDivElement> = (event): void => {
      if (disabled) {
        return;
      }

      onClick?.(event);
      handleSelect(event.nativeEvent);
    };

    const handleKeyDown: React.KeyboardEventHandler<HTMLDivElement> = (event): void => {
      if (event.key !== "Enter" && event.key !== " ") {
        return;
      }

      event.preventDefault();
      event.currentTarget.click();
    };

    const content = (
      <div
        ref={itemRef}
        data-slot='drop-drawer-item'
        data-disabled={disabled}
        data-inset={inset}
        role='menuitem'
        tabIndex={disabled ? -1 : 0}
        className={cn(
          styles.mobileItem,
          !isInsideGroup && styles.mobileStandaloneItem,
          isInsideGroup && styles.mobileGroupedItem,
          inset && styles.inset,
          className,
        )}
        onClick={handleClick}
        onKeyDown={handleKeyDown}
        aria-disabled={disabled}
        {...(props as React.HTMLAttributes<HTMLDivElement>)}>
        <div className={styles.itemChildren}>{children}</div>
        {icon ? <div className={styles.itemIcon}>{icon}</div> : null}
      </div>
    );

    const parentSubmenuId = props["data-parent-submenu-id"] ?? props["data-parent-submenu"];

    if (parentSubmenuId) {
      return content;
    }

    return (
      <BaseDrawer.Close
        nativeButton={false}
        render={content}
      />
    );
  }

  const handleDesktopClick: React.MouseEventHandler<HTMLElement> = (event): void => {
    if (disabled) {
      return;
    }

    onClick?.(event);
    handleSelect(event.nativeEvent);
  };

  return (
    <DropdownMenuItem
      data-slot='drop-drawer-item'
      data-inset={inset}
      className={cn(styles.desktopItem, className)}
      closeOnClick={closeOnClick}
      disabled={disabled}
      inset={inset}
      onClick={handleDesktopClick}
      {...props}>
      <div className={styles.itemRow}>
        <div className={styles.itemChildren}>{children}</div>
        {icon ? <div className={styles.itemIcon}>{icon}</div> : null}
      </div>
    </DropdownMenuItem>
  );
}

/**
 * Renders a visual separator between desktop drop drawer sections.
 *
 * @remarks
 * - Renders a separator only in desktop dropdown mode
 * - Built on Base UI Menu separator primitives
 *
 * @example
 * ```tsx
 * <DropDrawerSeparator />
 * ```
 *
 * @see {@link https://base-ui.com/react/components/menu | Base UI Menu Docs}
 */
function DropDrawerSeparator({
  className,
  ...props
}: React.ComponentPropsWithoutRef<typeof DropdownMenuSeparator>): React.JSX.Element | null {
  const {isMobile} = useDropDrawerContext();

  if (isMobile) {
    return null;
  }

  return (
    <DropdownMenuSeparator
      data-slot='drop-drawer-separator'
      className={className}
      {...props}
    />
  );
}

/**
 * Renders a section label for the drop drawer surface.
 *
 * @remarks
 * - Renders a drawer title on mobile and a menu label on desktop
 * - Built on Base UI Drawer and Menu primitives
 *
 * @example
 * ```tsx
 * <DropDrawerLabel>Actions</DropDrawerLabel>
 * ```
 *
 * @see {@link https://base-ui.com/react/components/menu | Base UI Menu Docs}
 */
function DropDrawerLabel({
  className,
  children,
  ...props
}: React.ComponentProps<typeof DropdownMenuLabel> | React.ComponentProps<typeof DrawerTitle>): React.JSX.Element {
  const {isMobile} = useDropDrawerContext();

  return isMobile ? (
    <DrawerHeader className={styles.mobileLabelWrapper}>
      <DrawerTitle
        data-slot='drop-drawer-label'
        className={cn(styles.mobileLabel, className)}
        {...(props as React.ComponentProps<typeof DrawerTitle>)}>
        {children}
      </DrawerTitle>
    </DrawerHeader>
  ) : (
    <DropdownMenuLabel
      data-slot='drop-drawer-label'
      className={className}
      {...(props as React.ComponentProps<typeof DropdownMenuLabel>)}>
      {children}
    </DropdownMenuLabel>
  );
}

/**
 * Renders footer content aligned to the bottom of the responsive surface.
 *
 * @remarks
 * - Renders a drawer footer on mobile and a styled `<div>` on desktop
 * - Built on Base UI Drawer primitives for mobile layouts
 *
 * @example
 * ```tsx
 * <DropDrawerFooter>Signed in as Alex</DropDrawerFooter>
 * ```
 *
 * @see {@link https://base-ui.com/react/components/drawer | Base UI Drawer Docs}
 */
function DropDrawerFooter({
  className,
  children,
  ...props
}: React.ComponentProps<typeof DrawerFooter> | React.ComponentProps<"div">): React.JSX.Element {
  const {isMobile} = useDropDrawerContext();

  return isMobile ? (
    <DrawerFooter
      data-slot='drop-drawer-footer'
      className={cn(styles.mobileFooter, className)}
      {...(props as React.ComponentProps<typeof DrawerFooter>)}>
      {children}
    </DrawerFooter>
  ) : (
    <div
      data-slot='drop-drawer-footer'
      className={cn(styles.desktopFooter, className)}
      {...props}>
      {children}
    </div>
  );
}

/**
 * Renders a grouped collection of drop drawer items.
 *
 * @remarks
 * - Renders a Base UI menu group on desktop and a `<div role="group">` on mobile
 * - Inserts mobile-only separators between adjacent children
 *
 * @example
 * ```tsx
 * <DropDrawerGroup>
 *   <DropDrawerItem>Profile</DropDrawerItem>
 *   <DropDrawerItem>Billing</DropDrawerItem>
 * </DropDrawerGroup>
 * ```
 *
 * @see {@link https://developer.mozilla.org/docs/Web/Accessibility/ARIA/Roles/group_role | ARIA Group Role}
 */
function DropDrawerGroup({className, children, ...props}: React.ComponentProps<"div"> & {children: React.ReactNode}): React.JSX.Element {
  const {isMobile} = useDropDrawerContext();

  const childrenWithSeparators = React.useMemo(() => {
    if (!isMobile) {
      return children;
    }

    const childArray = React.Children.toArray(children);
    const filteredChildren = childArray.filter((child) => !(React.isValidElement(child) && child.type === DropDrawerSeparator));

    return filteredChildren.flatMap((child, index) => {
      if (index === filteredChildren.length - 1) {
        return [child];
      }

      return [
        child,
        <div
          key={`separator-${index}`}
          className={styles.mobileGroupSeparator}
          aria-hidden='true'
        />,
      ];
    });
  }, [children, isMobile]);

  return isMobile ? (
    <div
      data-drop-drawer-group
      data-slot='drop-drawer-group'
      role='group'
      className={cn(styles.mobileGroup, className)}
      {...props}>
      {childrenWithSeparators}
    </div>
  ) : (
    <BaseMenu.Group
      data-drop-drawer-group
      data-slot='drop-drawer-group'
      className={className}
      {...(props as React.ComponentPropsWithoutRef<typeof BaseMenu.Group>)}>
      {children}
    </BaseMenu.Group>
  );
}

/**
 * Renders a submenu root within the drop drawer surface.
 *
 * @remarks
 * - Renders a Base UI submenu on desktop and a mobile-aware container on small screens
 * - Registers submenu content for animated mobile drill-down navigation
 *
 * @example
 * ```tsx
 * <DropDrawerSub>
 *   <DropDrawerSubTrigger>More</DropDrawerSubTrigger>
 *   <DropDrawerSubContent>
 *     <DropDrawerItem>Sub item</DropDrawerItem>
 *   </DropDrawerSubContent>
 * </DropDrawerSub>
 * ```
 *
 * @see {@link https://base-ui.com/react/components/menu | Base UI Menu Docs}
 */
function DropDrawerSub({
  children,
  id,
  ...props
}: React.ComponentPropsWithoutRef<typeof DropdownMenuSub> & {children?: React.ReactNode; id?: string}): React.JSX.Element {
  const {isMobile} = useDropDrawerContext();
  const {registerSubmenuContent} = React.useContext(SubmenuContext);
  const generatedId = React.useId();
  const submenuId = id || generatedId;

  React.useEffect(() => {
    if (!registerSubmenuContent) {
      return;
    }

    const contentItems: Array<React.ReactNode> = [];

    React.Children.forEach(children, (child) => {
      if (React.isValidElement(child) && child.type === DropDrawerSubContent) {
        const childElement = child as React.ReactElement<{children?: React.ReactNode}>;

        React.Children.forEach(childElement.props.children, (contentChild) => {
          contentItems.push(contentChild);
        });
      }
    });

    if (contentItems.length > 0) {
      registerSubmenuContent(submenuId, contentItems);
    }
  }, [children, registerSubmenuContent, submenuId]);

  if (isMobile) {
    const processedChildren = React.Children.map(children, (child) => {
      if (!React.isValidElement(child)) {
        return child;
      }

      if (child.type === DropDrawerSubTrigger || child.type === DropDrawerSubContent) {
        return React.cloneElement(child as React.ReactElement<MobileSubmenuDataAttributes>, {
          "data-parent-submenu": submenuId,
          "data-parent-submenu-id": submenuId,
          "data-submenu-id": submenuId,
        });
      }

      return child;
    });

    return (
      <div
        data-slot='drop-drawer-sub'
        data-submenu-id={submenuId}
        id={submenuId}>
        {processedChildren}
      </div>
    );
  }

  return (
    <DropdownMenuSub
      data-slot='drop-drawer-sub'
      data-submenu-id={submenuId}
      {...props}>
      {children}
    </DropdownMenuSub>
  );
}

interface DropDrawerSubTriggerProps
  extends Omit<React.ComponentPropsWithoutRef<typeof DropdownMenuSubTrigger>, "children" | "onClick">, MobileSubmenuDataAttributes {
  /**
   * Trigger contents.
   * @default undefined
   */
  children?: React.ReactNode;
  /**
   * Additional CSS classes merged with the trigger styles.
   * @default undefined
   */
  className?: string;
  /**
   * Whether to apply inset spacing to align the trigger with grouped content.
   * @default undefined
   */
  inset?: boolean;
  /**
   * Mouse click handler invoked before submenu navigation occurs.
   * @default undefined
   */
  onClick?: React.MouseEventHandler<HTMLElement>;
}

/**
 * Renders the trigger that opens a nested submenu.
 *
 * @remarks
 * - Renders a Base UI submenu trigger on desktop and a keyboard-accessible `<div>` on mobile
 * - Built on Base UI Menu submenu primitives
 *
 * @example
 * ```tsx
 * <DropDrawerSubTrigger>Advanced</DropDrawerSubTrigger>
 * ```
 *
 * @see {@link https://base-ui.com/react/components/menu | Base UI Menu Docs}
 */
function DropDrawerSubTrigger({className, inset, children, onClick, ...props}: DropDrawerSubTriggerProps): React.JSX.Element {
  const {isMobile} = useDropDrawerContext();
  const {navigateToSubmenu} = React.useContext(SubmenuContext);

  const isInGroup = React.useCallback((element: HTMLElement | null): boolean => {
    if (!element) {
      return false;
    }

    let parent = element.parentElement;

    while (parent) {
      if (parent.hasAttribute("data-drop-drawer-group")) {
        return true;
      }

      parent = parent.parentElement;
    }

    return false;
  }, []);

  const itemRef = React.useRef<HTMLDivElement>(null);
  const [isInsideGroup, setIsInsideGroup] = React.useState(false);

  React.useEffect(() => {
    if (!isMobile) {
      return;
    }

    const timer = globalThis.window.setTimeout(() => {
      if (itemRef.current) {
        setIsInsideGroup(isInGroup(itemRef.current));
      }
    }, 0);

    return () => globalThis.window.clearTimeout(timer);
  }, [isInGroup, isMobile]);

  if (isMobile) {
    const navigate = (eventTarget: HTMLElement): void => {
      let submenuId: string | null = null;
      const closestElement = eventTarget.closest("[data-submenu-id]");
      const closestId = closestElement?.getAttribute("data-submenu-id");

      if (closestId) {
        submenuId = closestId;
      }

      if (!submenuId) {
        submenuId = props["data-parent-submenu-id"] ?? props["data-parent-submenu"] ?? null;
      }

      if (!submenuId) {
        return;
      }

      const title = typeof children === "string" ? children : MOBILE_SUBMENU_TITLE;
      navigateToSubmenu?.(submenuId, title);
    };

    const handleClick: React.MouseEventHandler<HTMLDivElement> = (event): void => {
      event.preventDefault();
      event.stopPropagation();
      onClick?.(event);
      navigate(event.currentTarget);
    };

    const handleKeyDown: React.KeyboardEventHandler<HTMLDivElement> = (event): void => {
      if (event.key !== "Enter" && event.key !== " ") {
        return;
      }

      event.preventDefault();
      event.stopPropagation();
      event.currentTarget.click();
    };

    return (
      <div
        ref={itemRef}
        data-slot='drop-drawer-sub-trigger'
        data-inset={inset}
        role='menuitem'
        tabIndex={0}
        className={cn(
          styles.mobileItem,
          !isInsideGroup && styles.mobileStandaloneItem,
          isInsideGroup && styles.mobileGroupedItem,
          inset && styles.inset,
          className,
        )}
        onClick={handleClick}
        onKeyDown={handleKeyDown}
        {...(props as React.HTMLAttributes<HTMLDivElement>)}>
        <div className={styles.itemChildren}>{children}</div>
        <ChevronRightIcon className={styles.chevron} />
      </div>
    );
  }

  return (
    <DropdownMenuSubTrigger
      data-slot='drop-drawer-sub-trigger'
      data-inset={inset}
      className={className}
      inset={inset}
      onClick={onClick}
      {...props}>
      {children}
    </DropdownMenuSubTrigger>
  );
}

/**
 * Renders the content region for a nested submenu.
 *
 * @remarks
 * - Renders only in desktop dropdown mode
 * - Built on Base UI Menu submenu popup primitives
 *
 * @example
 * ```tsx
 * <DropDrawerSubContent>
 *   <DropDrawerItem>Details</DropDrawerItem>
 * </DropDrawerSubContent>
 * ```
 *
 * @see {@link https://base-ui.com/react/components/menu | Base UI Menu Docs}
 */
function DropDrawerSubContent({
  className,
  sideOffset = 4,
  children,
  ...props
}: React.ComponentProps<typeof DropdownMenuSubContent>): React.JSX.Element | null {
  const {isMobile} = useDropDrawerContext();

  if (isMobile) {
    return null;
  }

  return (
    <DropdownMenuSubContent
      data-slot='drop-drawer-sub-content'
      sideOffset={sideOffset}
      className={cn(styles.dropdownSubContent, className)}
      {...props}>
      {children}
    </DropdownMenuSubContent>
  );
}

DropDrawer.displayName = "DropDrawer";
DropDrawerTrigger.displayName = "DropDrawerTrigger";
DropDrawerContent.displayName = "DropDrawerContent";
DropDrawerItem.displayName = "DropDrawerItem";
DropDrawerSeparator.displayName = "DropDrawerSeparator";
DropDrawerLabel.displayName = "DropDrawerLabel";
DropDrawerFooter.displayName = "DropDrawerFooter";
DropDrawerGroup.displayName = "DropDrawerGroup";
DropDrawerSub.displayName = "DropDrawerSub";
DropDrawerSubTrigger.displayName = "DropDrawerSubTrigger";
DropDrawerSubContent.displayName = "DropDrawerSubContent";

export {
  DropDrawer,
  DropDrawerContent,
  DropDrawerFooter,
  DropDrawerGroup,
  DropDrawerItem,
  DropDrawerLabel,
  DropDrawerSeparator,
  DropDrawerSub,
  DropDrawerSubContent,
  DropDrawerSubTrigger,
  DropDrawerTrigger,
};
