import React, { useEffect, useState } from 'react';

type Props = {
  visible?: boolean;
  enterTime?: number;
  leaveTime?: number;
  clearTime?: number;
  className?: string;
  name?: string;
};

export type TransitionProps = Props;

export const Transition: React.FC<React.PropsWithChildren<TransitionProps | any>> = ({
  children,
  className = '',
  visible = false,
  enterTime = 60,
  leaveTime = 60,
  clearTime = 60,
  name = 'transition',
  ...props
}: React.PropsWithChildren<TransitionProps>) => { // !!! any
  const [classes, setClasses] = useState<string>('');
  const [renderable, setRenderable] = useState<boolean>(visible);
  useEffect(() => {
    const statusClassName = visible ? 'enter' : 'leave';
    const time = visible ? enterTime : leaveTime;
    if (visible && !renderable) {
      setRenderable(true);
    }
    setClasses(`${name}-${statusClassName}`);
    // set class to active
    const timer = setTimeout(() => {
      setClasses(`${name}-${statusClassName} ${name}-${statusClassName}-active`);
      clearTimeout(timer);
    }, time);
    // remove classess when animation over
    const clearClassesTimer = setTimeout(() => {
      if (!visible) {
        setClasses('');
        setRenderable(false);
      }
      clearTimeout(clearClassesTimer);
    }, time + clearTime);
    return () => {
      clearTimeout(timer);
      clearTimeout(clearClassesTimer);
    };
  }, [visible, renderable, enterTime, leaveTime, name, clearTime]);
  if (!React.isValidElement(children) || !renderable) {
    return null;
  }
  return React.cloneElement(children as React.ReactElement<HTMLElement>, { ...props, className: `${(children as React.ReactElement<HTMLElement>).props.className} ${className} ${classes}` });
};

Transition.displayName = 'Transition';
