import * as React from "react";
import classNames from "classnames";
// @ts-ignore
import Animated from "rc-animate/lib/CSSMotion";
import TreeNode, { TreeNodeProps } from "./tree-node";
import { FlattenNode } from "./interface";
import { getTreeNodeProps, TreeNodeRequiredProps } from "./util/tree-util";
import { TreeContext } from "./context-types";

interface MotionTreeNodeProps extends Omit<TreeNodeProps, "domRef"> {
  active: boolean;
  motion?: any;
  motionNodes?: FlattenNode[];
  onMotionEnd: () => void;
  motionType?: "show" | "hide";

  treeNodeRequiredProps: TreeNodeRequiredProps;
}

//Motion Tree Node component
const MotionTreeNode: React.FC<MotionTreeNodeProps> = (
  {
    className,
    style,
    motion,
    motionNodes,
    motionType,
    onMotionEnd,
    active,
    treeNodeRequiredProps,
    ...props
  },
  ref
) => {
  const [visible, setVisible] = React.useState(true);
  const { prefixCls } = React.useContext(TreeContext);

  React.useEffect(() => {
    if (motionNodes && motionType === "hide" && visible) {
      setVisible(false);
    }
  }, [motionNodes]);

  if (motionNodes) {
    return (
      <Animated
        ref={ref}
        visible={visible}
        {...motion}
        motionAppear={motionType === "show"}
        onAppearEnd={onMotionEnd}
        onLeaveEnd={onMotionEnd}
      >
        {({ className: motionClassName, style: motionStyle }, motionRef) => (
          <div
            ref={motionRef}
            className={classNames(
              `${prefixCls}-treenode-motion`,
              motionClassName
            )}
            style={motionStyle}
          >
            {motionNodes.map((treeNode: FlattenNode) => {
              const {
                data: { key, ...restProps },
                isStart,
                isEnd
              } = treeNode;
              delete restProps.children;

              const treeNodeProps = getTreeNodeProps(
                key,
                treeNodeRequiredProps
              );

              return (
                <TreeNode
                  {...restProps}
                  {...treeNodeProps}
                  active={active}
                  data={treeNode.data}
                  key={key}
                  isStart={isStart}
                  isEnd={isEnd}
                />
              );
            })}
          </div>
        )}
      </Animated>
    );
  }
  return (
    <TreeNode
      domRef={ref}
      className={className}
      style={style}
      {...props}
      active={active}
    />
  );
};

MotionTreeNode.displayName = "MotionTreeNode";

const RefMotionTreeNode = React.forwardRef(MotionTreeNode);

export { RefMotionTreeNode };
