import { clsx } from '@trail-ui/shared-utils';
import { MenuSlots, MenuVariantProps, SlotsToClasses, menu } from '@trail-ui/theme';
import { createContext, useMemo } from 'react';
import type { ListBoxProps as AriaListBoxProps } from 'react-aria-components';
import { ListBox as AriaListBox } from 'react-aria-components';

import { ListBoxItemProps } from './listbox-item';

export interface ListBoxProps<T> extends AriaListBoxProps<T>, MenuVariantProps {
  /**
   * The listbox classNames.
   */
  classNames?: SlotsToClasses<MenuSlots>;
  /**
   * The menu items classNames.
   */
  itemClasses?: ListBoxItemProps['classNames'];
}

interface InternalListBoxContextValue {
  itemClasses?: ListBoxItemProps['classNames'];
}

export const InternalListBoxContext = createContext<InternalListBoxContextValue>(
  {} as InternalListBoxContextValue,
);

export function ListBox<T extends object>(props: ListBoxProps<T>) {
  const { children, className, classNames, itemClasses, ...otherProps } = props;

  const slots = useMemo(() => menu(), []);

  const baseStyles = clsx(classNames?.base, className);

  return (
    <InternalListBoxContext.Provider value={{ itemClasses }}>
      <AriaListBox className={slots.base({ class: baseStyles })} {...otherProps}>
        {children}
      </AriaListBox>
    </InternalListBoxContext.Provider>
  );
}
