import React, { ReactNode, ReactElement, useEffect, useCallback } from 'react';
import css from '../../utils/css';

import { Wrapper, Container } from './StyledCollapse';

import { CommonProps } from '../common';
import { useResizeObserver } from '../../utils/hooks';

export interface CollapseProps extends CommonProps {
  /*
   * The collapse's content.
   */
  children: ReactNode;
  /**
   * Whether the child components will remain mounted when the Collapse is closed.
   */
  keepChildrenMounted?: boolean;
  /**
   * Whether the component is open or closed.
   */
  open?: boolean;
}

const Collapse = ({
  open = false,
  keepChildrenMounted = false,
  children,
  id,
  className,
  style,
  sx = {},
  'data-test-id': dataTestId,
}: CollapseProps): ReactElement => {
  const innerRef = React.useRef(null);
  const [contentHeight, setContentHeight] = React.useState<number>(0);
  const [alreadyOpen, setAlreadyOpen] = React.useState<boolean>(false);
  const [isWaitingToClose, setIsWaitingToClose] = React.useState<boolean>(
    false
  );

  const resizeCallback = useCallback(
    ({ height }) => {
      setContentHeight(height);
    },
    [setContentHeight]
  );

  useEffect(() => {
    if (open === true) {
      setIsWaitingToClose(true);
    } else {
      setAlreadyOpen(false);
    }

    const timerId = setTimeout((): void => {
      if (open === true) {
        setAlreadyOpen(true);
      } else {
        setIsWaitingToClose(false);
      }
    }, 300);

    return (): void => {
      clearTimeout(timerId);
    };
  }, [open]);

  useResizeObserver(resizeCallback, innerRef.current);

  return (
    <Wrapper
      open={open}
      contentHeight={contentHeight}
      alreadyOpen={alreadyOpen}
      id={id}
      className={className}
      style={{ ...style, ...css(sx) }}
      data-test-id={dataTestId}
    >
      {(keepChildrenMounted === true ||
        open === true ||
        (open === false && isWaitingToClose === true)) && (
        <Container ref={innerRef}>{children}</Container>
      )}
    </Wrapper>
  );
};

export default Collapse;
