import { useEffect, useState } from "preact/compat";
import EvEmitter from 'ev-emitter';
import classNames from 'classnames';
import useId from "../utilities/useId";
import { InlineError } from "../InlineError";
import { Label } from "../Label";
import { useLabelProps } from "../Label/useLabelProps";
import { useHint } from "../Hint/useHint";
import cleanFieldProps from "../utilities/cleanFieldProps";
import describeField from "../utilities/describeField";
import { jsx as _jsx, jsxs as _jsxs } from "preact/compat/jsx-runtime";
/** Used to emit events to all Choice components */
const dsChoiceEmitter = new EvEmitter();

/**
 * This component passes any additional props to its underlying input element
 * as attributes. See the corresponding MDN documentation for
 * [input](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) for
 * a list of valid attributes.

 * For information about how and when to use this component, refer to the
 * [checkbox](https://design.cms.gov/components/checkbox/) and
 * [radio](https://design.cms.gov/components/radio/) documentation pages.
 */

export const Choice = _ref => {
  let {
    _choiceChild,
    ...props
  } = _ref;
  const initialCheckedState = props.checked ?? props.defaultChecked;
  const [internalCheckedState, setChecked] = useState(initialCheckedState);
  const isControlled = props.checked !== undefined;
  const checked = isControlled ? props.checked : internalCheckedState;
  const radioCheckedEventName = `${props.name}-radio-checked`;
  const id = useId('choice--', props.id);
  const {
    hintId,
    hintElement
  } = useHint({
    ...props,
    id
  });
  const labelProps = useLabelProps({
    ...props,
    id
  });
  let errorId;
  let errorElement;
  if (!_choiceChild) {
    errorId = props.errorId ?? `${id}__error`;
    errorElement = /*#__PURE__*/_jsx(InlineError, {
      id: errorId,
      inversed: props.inversed,
      className: props.errorMessageClassName,
      children: props.errorMessage
    });
  }

  // Subscribe to changes from other radio buttons in the same group
  useEffect(() => {
    // This logic only applies to uncontrolled radio groups
    if (props.type !== 'radio' || isControlled) {
      return;
    }
    const handleRadioChecked = checkedId => {
      // A radio button in this group was just checked. If it wasn't this one, uncheck this one
      if (checkedId !== id) {
        setChecked(false);
      }
    };
    dsChoiceEmitter.on(radioCheckedEventName, handleRadioChecked);
    return () => {
      dsChoiceEmitter.off(radioCheckedEventName, handleRadioChecked);
    };
  }, [setChecked]);
  function handleChange(event) {
    if (props.onChange) {
      props.onChange(event);
    }
    if (!isControlled) {
      setChecked(event.target.checked);
      if (props.type === 'radio' && event.target.checked) {
        // Emit an event so other radio options can uncheck themselves
        dsChoiceEmitter.emitEvent(radioCheckedEventName, [id]);
      }
    }
  }
  const {
    'aria-live': ariaLive,
    'aria-relevant': ariaRelevant,
    'aria-atomic': ariaAtomic,
    className,
    inversed,
    inputClassName,
    inputRef,
    size,
    checkedChildren,
    uncheckedChildren,
    ...inputProps
  } = props;
  return /*#__PURE__*/_jsxs("div", {
    className: className,
    "aria-live": ariaLive ?? (checkedChildren ? 'polite' : null),
    "aria-relevant": ariaRelevant ?? (checkedChildren ? 'additions text' : null),
    "aria-atomic": ariaAtomic ?? (checkedChildren ? 'false' : null),
    children: [/*#__PURE__*/_jsxs("div", {
      className: "ds-c-choice-wrapper",
      children: [/*#__PURE__*/_jsx("input", {
        ...cleanFieldProps(inputProps),
        id: id,
        className: classNames(inputClassName, 'ds-c-choice', {
          'ds-c-choice--inverse': inversed,
          'ds-c-choice--small': size === 'small'
        }),
        onChange: handleChange,
        ref: inputRef,
        "aria-describedby": describeField({
          ...props,
          errorId,
          hintId
        })
      }), /*#__PURE__*/_jsx(Label, {
        ...labelProps,
        fieldId: id
      }), hintElement, errorElement]
    }), checked ? checkedChildren : uncheckedChildren]
  });
};
Choice.defaultProps = {
  _choiceChild: false
};
export default Choice;