import { useEffect, useState } from 'react';

/**
 * A helper component for managing the rendering of components that
 * need to stay in the DOM a bit longer to finish their CSS exit animation.
 *
 * In the future, replace this component with plain CSS once that is feasible.
 * This will require broader support for `transition-behavior: allow-discrete`
 * and https://developer.mozilla.org/en-US/docs/Web/CSS/overlay.
 */
export const ExitAnimationWrapper: React.FC<{
  /**
   * Set this to true to indicate that the nested component should be rendered
   */
  isActive: boolean;
  /**
   * How long the component should be rendered after `isActive` was set to `false`
   */
  delayMs?: number;
  /**
   * Set this to true to also delay the entry of the nested component until after
   * another one has exited full.
   */
  withEntryDelay?: boolean;
  /**
   * Render prop that provides the nested component with the `delayedIsActive` flag
   */
  children: (delayedIsActive: boolean) => React.ReactNode;
}> = ({ isActive = false, delayMs = 500, withEntryDelay, children }) => {
  const [delayedIsActive, setDelayedIsActive] = useState(false);

  useEffect(() => {
    if (isActive && !withEntryDelay) {
      setDelayedIsActive(true);

      return () => '';
    } else {
      const timeout = setTimeout(() => {
        setDelayedIsActive(isActive);
      }, delayMs);

      return () => {
        clearTimeout(timeout);
      };
    }
  }, [isActive, delayMs, withEntryDelay]);

  if (!isActive && !delayedIsActive) {
    return null;
  }

  return children(isActive && delayedIsActive);
};
