import React, { LegacyRef } from 'react';
import classNames from 'classnames';
import { useFormikContext } from 'formik';
import { FormDefaults } from './FormDefaults';

export interface SubmitFormButtonProps
  extends Omit<React.HTMLProps<HTMLButtonElement>, 'type'> {
  /** Allow the form to be submitted without any changes. By default this is not allowed. */
  allowPristineSubmit?: boolean;
  /** Text to display on the button. Default text is 'Submit'. */
  children?: React.ReactNode;
}

function SubmitFormButton(
  {
    allowPristineSubmit,
    children,
    disabled,
    title,
    className,
    ...props
  }: SubmitFormButtonProps,
  ref: LegacyRef<HTMLButtonElement>
) {
  const { isSubmitting, dirty } = useFormikContext();
  const preventSubmit = (!dirty && !allowPristineSubmit) || isSubmitting;
  const buttonName = typeof children === 'string' ? children : 'Submit';
  return (
    <button
      {...props}
      ref={ref}
      type="submit"
      disabled={preventSubmit || disabled}
      aria-label={buttonName}
      title={
        title || isSubmitting
          ? 'Loading, please wait...'
          : preventSubmit
          ? "You haven't made any changes"
          : ''
      }
      className={classNames(
        FormDefaults.cssClassPrefix + 'submit-form-button',
        className
      )}>
      {children || 'Submit'}
    </button>
  );
}

/** Generic submit button for forms. */
export default React.forwardRef(
  SubmitFormButton
) as React.FunctionComponent<SubmitFormButtonProps>;
