import { cva } from 'class-variance-authority'
import { cn } from '../../utils/cn'

export const BUTTON_SET_SIZE_OPTIONS = ['default', 'sm', 'xs'] as const
export type ButtonSetSize = (typeof BUTTON_SET_SIZE_OPTIONS)[number]

export const BUTTON_SET_ORIENTATION_OPTIONS = [
  'responsive',
  'horizontal',
  'vertical',
] as const
export type ButtonSetOrientation =
  (typeof BUTTON_SET_ORIENTATION_OPTIONS)[number]

export type ButtonSetProps = React.PropsWithChildren<{
  /** Controls the height, padding, and typography density of all child buttons. */
  size?: ButtonSetSize
  /**
   * Layout direction of the button group.
   * - `responsive` (default): stacks vertically on mobile, flows horizontally on desktop.
   * - `horizontal`: always flows in a row, each button sharing equal width.
   * - `vertical`: always stacks in a column, each button full width.
   */
  orientation?: ButtonSetOrientation
  className?: string
}>
// Explicitely set button sizing to avoid having to use React.cloneChildren,
// which is not preferable for a component as low-level as Button
// This is verbose, but it's better for performance
const buttonSetVariants = cva(
  'gap-2 [&_[data-slot="button"]]:whitespace-normal [&_[data-slot="button"]]:break-words',
  {
    variants: {
      orientation: {
        responsive:
          'flex flex-col md:flex-row [&_button]:w-full md:[&_button]:flex-1 md:[&_button]:basis-0',
        horizontal:
          'flex flex-row [&_button]:flex-1 [&_button]:basis-0 [&_button]:whitespace-normal',
        vertical: 'flex flex-col [&_button]:w-full',
      },
      size: {
        default:
          '[&_[data-slot="button"]]:max-h-12 [&_[data-slot="button"]]:min-h-12 [&_[data-slot="button"]]:px-6 [&_[data-slot="button"]]:py-3.5 [&_[data-slot="button"]_svg]:!size-4',
        sm: '[&_[data-slot="button"]]:max-h-10 [&_[data-slot="button"]]:min-h-10 [&_[data-slot="button"]]:px-6 [&_[data-slot="button"]]:py-3 [&_[data-slot="button"]_svg]:!size-3',
        xs: '[&_[data-slot="button"]]:max-h-8 [&_[data-slot="button"]]:min-h-8 [&_[data-slot="button"]]:px-4 [&_[data-slot="button"]]:py-2 [&_[data-slot="button"]_svg]:!size-3',
      },
    },
    compoundVariants: [
      {
        orientation: 'horizontal',
        size: 'default',
        className:
          '[&_[data-slot="button"]]:min-w-[120px] [&_[data-slot="button"]]:max-w-[200px]',
      },
      {
        orientation: 'horizontal',
        size: 'sm',
        className:
          '[&_[data-slot="button"]]:min-w-[96px] [&_[data-slot="button"]]:max-w-[200px]',
      },
      {
        orientation: 'horizontal',
        size: 'xs',
        className:
          '[&_[data-slot="button"]]:min-w-[72px] [&_[data-slot="button"]]:max-w-[120px]',
      },
      {
        orientation: 'responsive',
        size: 'default',
        className:
          'md:[&_[data-slot="button"]]:min-w-[120px] md:[&_[data-slot="button"]]:max-w-[200px]',
      },
      {
        orientation: 'responsive',
        size: 'sm',
        className:
          'md:[&_[data-slot="button"]]:min-w-[96px] md:[&_[data-slot="button"]]:max-w-[200px]',
      },
      {
        orientation: 'responsive',
        size: 'xs',
        className:
          'md:[&_[data-slot="button"]]:min-w-[72px] md:[&_[data-slot="button"]]:max-w-[120px]',
      },
    ],
  },
)

/**
 * Groups related buttons with consistent sizing and layout. Enforces uniform
 * size across all child buttons without needing to set it on each one.
 */
export function ButtonSet({
  children,
  size = 'default',
  orientation = 'responsive',
  className,
}: ButtonSetProps) {
  return (
    <div
      className={cn(buttonSetVariants({ orientation, size }), className)}
      data-buttonset-size={size}
    >
      {children}
    </div>
  )
}

ButtonSet.displayName = 'ButtonSet'

export default ButtonSet
