import {
  createContext,
  useState,
  useEffect,
  CSSProperties,
  ReactNode,
  Children,
  ReactElement,
  cloneElement,
} from 'react'
import classNames from 'classnames'
import { CommonComponentProps } from '../../utils/types'
import { pickNullish } from '../../utils'

import { RadioProps } from './Radio'

export interface RadioGroupContext {
  value: any
  onChange: (value: any) => any
}

export const RadioGroupContext = createContext<RadioGroupContext | null>(null)

export interface RadioGroupProps extends CommonComponentProps {
  className?: string
  style?: CSSProperties
  value?: any
  defaultValue?: any
  vertical?: boolean
  disabled?: boolean
  size?: string
  type?: RadioProps['type']
  icon?: (checked: boolean) => ReactNode
  checkedColor?: string
  children?: any
  onChange?: (value: any) => any
}

export function RadioGroup(props: RadioGroupProps) {
  const {
    className,
    value,
    defaultValue,
    vertical,
    disabled,
    size,
    type,
    icon,
    checkedColor,
    children,
    onChange,
    ...restProps
  } = props

  const [innerValue, setInnerValue] = useState(value ?? defaultValue ?? '')
  // 受控
  if (value != null) {
    useEffect(() => {
      setInnerValue(value)
    })
  }

  const innerChange = (val: any) => {
    // 非受控
    if (value == null) {
      setInnerValue(val)
    }
    onChange?.(val)
  }

  const context = {
    value: innerValue,
    onChange: innerChange,
  }

  const radioGroupClass = classNames(
    's-radio-group',
    {
      's-radio-group-vertical': vertical,
    },
    className
  )

  return (
    <div {...restProps} className={radioGroupClass}>
      <RadioGroupContext.Provider value={context}>
        {Children.map(
          children as ReactElement<RadioProps>,
          (element: ReactElement<RadioProps>) => {
            return cloneElement(element, {
              ...element.props,
              ...pickNullish(element.props, props, [
                'disabled',
                'size',
                'icon',
                'checkedColor',
                'type',
              ]),
            })
          }
        )}
      </RadioGroupContext.Provider>
    </div>
  )
}

export default RadioGroup
