import { type FocusTrapOptions, trapFocus } from '@zag-js/focus-trap';
import { track, trackSplit, effect } from 'ripple';
import { mergeProps } from 'zag-ripple';
import { splitFocusTrapProps } from './split-focus-trap-props.ripple';
import { ark } from '../factory';
import type { HTMLProps, MaybeTracked, PolymorphicProps } from '../../types';

export interface TrapOptions extends Pick<
  FocusTrapOptions,
  'onActivate' | 'onDeactivate' | 'initialFocus' | 'fallbackFocus' | 'returnFocusOnDeactivate' | 'setReturnFocus'
> {
  /**
 * Whether the focus trap is disabled.
 */
  disabled?: boolean;
}

export interface FocusTrapBaseProps extends PolymorphicProps<'div'>, TrapOptions {}

export interface FocusTrapProps extends HTMLProps<'div'>, FocusTrapBaseProps {}

export component FocusTrap(props: MaybeTracked<FocusTrapProps>) {
  const [children, rest] = trackSplit(props, ['children']);
  const [trapProps, localProps] = splitFocusTrapProps(@rest);

  let elem = track<HTMLDivElement | null>(null);

  effect(() => {
    const node = @elem;
    if (!node || @trapProps.disabled) return;
    return trapFocus(node, mergeProps(@trapProps));
  });

  <ark.div
    {...@localProps}
    {ref (el: HTMLDivElement | null) => {
      @elem = el;
    }}
  >
    <@children />
  </ark.div>
}
