import { forwardRef } from 'react';
import type { HTMLAttributes } from 'react';
import { cx } from '../../utils/cx';
import './Stack.css';

export type StackGap = 'none' | '3xs' | '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl';
export type StackAlign = 'start' | 'center' | 'end' | 'stretch' | 'baseline';
export type StackJustify = 'start' | 'center' | 'end' | 'between' | 'around';

export interface StackProps extends HTMLAttributes<HTMLDivElement> {
  /** `vertical` (default) stacks children in a column. */
  direction?: 'vertical' | 'horizontal';
  /** Gap between children, from the spacing scale. */
  gap?: StackGap;
  align?: StackAlign;
  justify?: StackJustify;
  /** Allows children to wrap onto multiple lines. Horizontal stacks only. */
  wrap?: boolean;
}

/**
 * Flexbox layout primitive. Use it for spacing between components so that
 * gaps come from the token scale rather than ad-hoc margins.
 */
export const Stack = forwardRef<HTMLDivElement, StackProps>(function Stack(
  {
    direction = 'vertical',
    gap = 'md',
    align,
    justify,
    wrap = false,
    className,
    children,
    ...rest
  },
  ref,
) {
  return (
    <div
      {...rest}
      ref={ref}
      className={cx(
        'ds-stack',
        `ds-stack--${direction}`,
        `ds-stack--gap-${gap}`,
        align && `ds-stack--align-${align}`,
        justify && `ds-stack--justify-${justify}`,
        wrap && 'ds-stack--wrap',
        className,
      )}
    >
      {children}
    </div>
  );
});
