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

export type StackSpace = SpaceToken

export interface StackProps extends HTMLAttributes<HTMLElement> {
  /** Vertical gap between children. Maps to Tailwind `gap-{space}`. */
  space?: StackSpace
  /** Render as a different element (e.g. `<section>`, `<article>`). Defaults to `div`. */
  as?: ElementType
  /** Center children horizontally (sets `items-center`). */
  align?: 'start' | 'center' | 'end' | 'stretch'
  /** Distribute vertical space (sets `justify-{value}`). */
  justify?: 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly'
  /** Stretch the stack to fill its parent's height. */
  fill?: boolean
  children?: ReactNode
}

const ALIGN_CLASS: Record<NonNullable<StackProps['align']>, string> = {
  start: 'items-start',
  center: 'items-center',
  end: 'items-end',
  stretch: 'items-stretch',
}

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

/**
 * Vertical stack with a consistent gap between children. This is the
 * single sanctioned way to space block-level elements in the admin —
 * never reach for `space-y-*` directly.
 */
export function Stack({
  space = '4',
  as: Component = 'div',
  align,
  justify,
  fill,
  className = '',
  children,
  ...rest
}: StackProps) {
  const classes = [
    'flex flex-col',
    `gap-${space}`,
    align ? ALIGN_CLASS[align] : '',
    justify ? JUSTIFY_CLASS[justify] : '',
    fill ? 'h-full' : '',
    className,
  ]
    .filter(Boolean)
    .join(' ')

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