import { useState } from 'react';

import Radio from '../radio';
import { RadioProps } from '../radio/Radio';
import { useInputAttributes, WithInputAttributesProps } from '../inputs/contexts';

export type RadioGroupRadio<T extends string | number = string> = Omit<
  RadioProps<T>,
  'name' | 'checked' | 'onChange' | 'className'
>;

export interface RadioGroupProps<T extends string | number = string> {
  name: string;
  radios: readonly RadioGroupRadio<T>[];
  selectedValue?: T; // TODO: `NoInfer<T>` from TypeScript 5.4
  onChange: NonNullable<RadioProps<T>['onChange']>;
  UNSAFE_inputAttributes?: WithInputAttributesProps['inputAttributes'];
}

export default function RadioGroup<T extends string | number = never>({
  name,
  radios,
  selectedValue: controlledValue,
  onChange,
  UNSAFE_inputAttributes,
}: RadioGroupProps<T>) {
  const inputAttributes = useInputAttributes({ nonLabelable: true });

  const [uncontrolledValue, setUncontrolledValue] = useState(controlledValue);

  return radios.length > 0 ? (
    <div
      role="radiogroup"
      {...inputAttributes}
      {...UNSAFE_inputAttributes}
      className="wds-radio-group"
    >
      {radios.map(({ value = '' as T, ...restProps }, index) => (
        <Radio
          // eslint-disable-next-line react/no-array-index-key
          key={index}
          {...restProps}
          name={name}
          value={value}
          checked={value === uncontrolledValue}
          onChange={(nextValue) => {
            setUncontrolledValue(nextValue);
            onChange(nextValue);
          }}
        />
      ))}
    </div>
  ) : null;
}
