import { ChangeEventHandler } from 'react';

import { useId } from '../../hooks/useId';
import { useTestIdAttribute } from '../../hooks/useTestIdAttribute';
import { assertEmptyObject } from '../../utils/assertEmptyObject';
import { SupportedInputProps } from '../types';

import { StyledRadioInput } from './styled';

export interface RadioProps extends Omit<SupportedInputProps<boolean>, 'value' | 'placeholder'> {
  /**
   * Value of radio button.
   *
   * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input#value
   */
  value: string;
  /**
   * If true, then Radio is checked.
   *
   * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input#checked
   */
  checked?: boolean;
}

/**
 * Radio button with given label.
 *
 * ```tsx
 * import { Radio } from 'ui-kit';
 *
 * <Radio value="subscribe" onChange={console.log} checked />
 * ```
 */
export function Radio(props: RadioProps) {
  const {
    id,
    onChange,
    checked,
    ariaLabel,
    ariaInvalid,
    ariaDescribedBy,
    ariaErrorMessage,
    disabled,
    value,
    className,
    onBlur,
    ariaRequired,
    required,
    testId,
    ...rest
  } = props;
  assertEmptyObject(rest);

  const testIdAttribute = useTestIdAttribute();
  const newId = useId();

  const handleChange: ChangeEventHandler<HTMLInputElement> = (event) => {
    if (onChange) {
      onChange(event.target.checked);
    }
  };

  return (
    <StyledRadioInput
      aria-describedby={ariaDescribedBy}
      aria-errormessage={ariaErrorMessage}
      aria-invalid={ariaInvalid}
      aria-label={ariaLabel}
      aria-required={ariaRequired}
      checked={!!checked}
      className={className}
      disabled={disabled}
      id={id ?? newId}
      onBlur={onBlur}
      onChange={handleChange}
      required={required}
      type="radio"
      value={value}
      {...{ [testIdAttribute]: testId }}
    />
  );
}
