import React, { ReactElement, ReactNode, ChangeEvent } from 'react';
import css from '../../utils/css';
import { Label, HiddenInput, LabelText } from './StyledCheckbox';

import { CommonProps } from '../common';

export interface CheckboxProps extends Omit<CommonProps, 'id'> {
  /**
   * Whether the checkbox is checked.
   */
  checked?: boolean;
  /**
   * Whether the checkbox is disabled.
   */
  disabled?: boolean;
  /**
   * Id of <input> element.
   */
  id?: string;
  /**
   * Whether the checkbox is in indeterminate checked state.
   */
  indeterminate?: boolean;
  /**
   * Name of <input> element, is used to refer to the form data for submission.
   */
  name?: string;
  /**
   * Set the handler to handle `change` event.
   */
  onChange?: (e: ChangeEvent<HTMLInputElement>) => void;
  /**
   * Checkbox text.
   */
  text: ReactNode;
  /**
   * Checkbox input value.
   */
  value: string | number;
}

const setIndeterminate = (
  target: HTMLInputElement | null,
  value: boolean | undefined
): void => {
  if (target !== null && value !== undefined) {
    // eslint-disable-next-line no-param-reassign
    target.indeterminate = value;
  }
};

const Checkbox = ({
  value,
  text,
  checked,
  indeterminate,
  onChange,
  disabled,
  name,
  id,
  className,
  style,
  sx = {},
  'data-test-id': dataTestId,
}: CheckboxProps): ReactElement => {
  const inputRef = React.useRef(null);
  React.useEffect(() => {
    setIndeterminate(inputRef.current, indeterminate);
  }, [indeterminate]);

  return (
    <Label className={className} style={{ ...style, ...css(sx) }}>
      <HiddenInput
        value={value}
        type="checkbox"
        name={name}
        checked={checked}
        ref={inputRef}
        disabled={disabled}
        onChange={onChange}
        id={id}
        data-test-id={dataTestId}
      />
      <LabelText>{text}</LabelText>
    </Label>
  );
};

export default Checkbox;
