import { track, trackSplit, type Tracked } from 'ripple';
import { usePresence, type UsePresenceReturn } from '../presence/use-presence.ripple';
import { type RenderStrategyProps } from '../../utils/render-strategy.ripple';
import { parts } from './swap.anatomy';

export interface UseSwapProps extends RenderStrategyProps {
  /**
 * Whether the swap is in the "on" state.
 * @default false
 */
  swap?: boolean;
}

export interface IndicatorProps {
  type: 'on' | 'off';
}

export interface UseSwapReturn {
  /**
 * Whether the swap is in the "on" state.
 */
  swap: boolean;
  /**
 * The presence instance for the "on" indicator.
 */
  onPresence: UsePresenceReturn;
  /**
 * The presence instance for the "off" indicator.
 */
  offPresence: UsePresenceReturn;
  /**
 * Props for the root element.
 */
  getRootProps: () => Record<string, unknown>;
  /**
 * Props for the indicator element.
 */
  getIndicatorProps: (props: IndicatorProps) => Record<string, unknown>;
}

export function useSwap(props: Tracked<UseSwapProps> = {}) {
  const [swap, lazyMount, unmountOnExit] = trackSplit(props, [
    'swap',
    'lazyMount',
    'unmountOnExit',
  ]);

  const presenceProps = {
    lazyMount: @lazyMount,
    unmountOnExit: @unmountOnExit,
    skipAnimationOnMount: true,
  };

  const present = track(() => @swap);
  const absent = track(() => !@swap);

  const onPresence = usePresence({ present, ...presenceProps });
  const offPresence = usePresence({ present: absent, ...presenceProps });

  return track(
    () => ({
      swap: @swap,
      onPresence: @onPresence,
      offPresence: @offPresence,
      getRootProps() {
        return {
          ...parts.root.attrs,
          'data-swap': @swap ? 'on' : 'off',
          style: { display: 'inline-grid' },
        };
      },
      getIndicatorProps({ type }: { type: 'on' | 'off' }) {
        const presence =
          type === 'on' ? onPresence : offPresence;
        return {
          ...parts.indicator.attrs,
          ...@presence.getPresenceProps(),
          'data-type': type,
          style: { gridArea: '1 / 1', display: 'inline-flex' },
        };
      },
    }),
  );
}
