import type { HTMLAttributes, ReactNode, ElementType } from 'react'
import type { SpaceToken } from './tokens.js'

export type ClusterAlign = 'start' | 'center' | 'end' | 'baseline' | 'stretch'
export type ClusterJustify = 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly'

export interface ClusterProps extends HTMLAttributes<HTMLElement> {
  /** Gap between children. Maps to Tailwind `gap-{space}`. */
  space?: SpaceToken
  /** Render as a different element. Defaults to `div`. */
  as?: ElementType
  /** Align items on the cross axis. */
  align?: ClusterAlign
  /** Distribute items along the main axis. */
  justify?: ClusterJustify
  /** Reverse the order of children. */
  reverse?: boolean
  /** Disable wrapping (default: true, items wrap on overflow). */
  noWrap?: boolean
  children?: ReactNode
}

const ALIGN_CLASS: Record<ClusterAlign, string> = {
  start: 'items-start',
  center: 'items-center',
  end: 'items-end',
  baseline: 'items-baseline',
  stretch: 'items-stretch',
}

const JUSTIFY_CLASS: Record<ClusterJustify, string> = {
  start: 'justify-start',
  center: 'justify-center',
  end: 'justify-end',
  between: 'justify-between',
  around: 'justify-around',
  evenly: 'justify-evenly',
}

/**
 * Horizontal cluster of items with a consistent gap, wrapping by default.
 * The canonical use case is action toolbars (`<Cluster justify="end">`),
 * badge groups, breadcrumbs, etc. Never reach for `flex flex-wrap gap-2`
 * directly — use Cluster.
 */
export function Cluster({
  space = '2',
  as: Component = 'div',
  align = 'center',
  justify = 'start',
  reverse,
  noWrap,
  className = '',
  children,
  ...rest
}: ClusterProps) {
  const classes = [
    'flex',
    reverse ? 'flex-row-reverse' : 'flex-row',
    noWrap ? 'flex-nowrap' : 'flex-wrap',
    `gap-${space}`,
    ALIGN_CLASS[align],
    JUSTIFY_CLASS[justify],
    className,
  ]
    .filter(Boolean)
    .join(' ')

  return (
    <Component className={classes} {...rest}>
      {children}
    </Component>
  )
}
