import { useEffect } from 'react';
import { useFormikContext } from 'formik';
import smoothscroll from 'smoothscroll-polyfill';
import { ServerErrorContextProps } from './ServerErrorContext';

export interface FocusErrorProps {
  /** Validation errors that have been received from the server. */
  serverErrors: ServerErrorContextProps;
}

/** Function to scroll to the field that has an error. */
export default function FocusError(props: FocusErrorProps) {
  const { errors, isSubmitting, isValidating } = useFormikContext();
  smoothscroll.polyfill();
  useEffect(() => {
    if (!isSubmitting || isValidating) {
      return;
    }
    //This block handles any front-end input validation errors
    //e.g. required fields, max characters, etc
    const keys = Object.keys(errors);
    if (keys.length > 0) {
      return scrollToErrorElement(keys);
    }
    //This block handles any input-specific server-side errors
    //e.g. improper email formatting, invalid phone number, etc.
    if (
      props.serverErrors.errors &&
      Object.values(props.serverErrors.errors).some((x) => !!x)
    ) {
      const names = Object.keys(props.serverErrors.errors);
      return scrollToErrorElement(names);
    }
  }, [errors, isSubmitting, isValidating, props]);
  return null;
}

const scrollToErrorElement = (keys: string[]) => {
  let firstErrorElement: HTMLElement | null = document.getElementById(
    `${keys[0].toLowerCase()}-error-scroll-target`
  );
  if (!firstErrorElement || !firstErrorElement.parentNode) {
    return;
  }
  firstErrorElement = firstErrorElement.parentNode as HTMLElement;
  const headerOffset = -110;
  const y =
    firstErrorElement.getBoundingClientRect().top +
    window.pageYOffset +
    headerOffset;
  window.scrollTo({ top: y, behavior: 'smooth' });
  setTimeout(() => {
    firstErrorElement?.focus();
  }, 500);
};
