import { useCallback, useMemo, useState } from 'react'

import { styled, vui } from '../core'
import { ChangeEvent, cs, filterUndefined } from '../utils'
import { RadioGroupProvider } from './context'
import { RadioGroupProps } from './radioGroup.types'

export const RadioGroupBase = styled.divBox`
  display: flex;
  flex-direction: column;
  gap: 1;
`

/**
 * Organizes layout and display of multiple radio buttons as a row or column.
 * Exposes some props to the children via context.
 */
export const RadioGroup = vui<'div', RadioGroupProps>((props, ref) => {
  const { className, defaultValue, disabled, isRow, name, onBlur, onChange, onFocus, size, value, variant, ...rest } =
    props
  const [isChecked, setIsChecked] = useState(value ?? defaultValue)

  const handleOnChange = useCallback(
    (e: ChangeEvent) => {
      setIsChecked(e.target.value)
      onChange?.(e)
    },
    [onChange],
  )

  const context = useMemo(
    () =>
      filterUndefined({
        defaultValue,
        disabled,
        isChecked,
        name,
        onBlur,
        onChange: handleOnChange,
        onFocus,
        size,
        value,
        variant,
      }),
    [defaultValue, disabled, handleOnChange, isChecked, name, onBlur, onFocus, size, value, variant],
  )

  const aliasedProps = filterUndefined({
    flexDirection: isRow ? 'row' : undefined,
  } as const)

  return (
    <RadioGroupProvider value={context}>
      <RadioGroupBase className={cs('vui-radioGroup', className)} ref={ref} {...aliasedProps} {...rest} />
    </RadioGroupProvider>
  )
})

RadioGroup.displayName = 'RadioGroup'

export default RadioGroup
