import React, { forwardRef } from "react";
import ReactDOM from "react-dom";
import { mergeRefs } from "../_util/merge-refs";
import { attachProps } from "../_util/attach-props";

interface DomRefProps {
  children?: React.ReactNode;
}

class DomRefInner extends React.Component<
  DomRefProps & { domRef: React.Ref<HTMLElement> }
> {
  public componentDidMount() {
    const dom = ReactDOM.findDOMNode(this) as HTMLElement; // eslint-disable-line react/no-find-dom-node
    const { domRef } = this.props;
    mergeRefs(domRef)(dom);
  }

  public componentDidUpdate() {
    const dom = ReactDOM.findDOMNode(this) as HTMLElement; // eslint-disable-line react/no-find-dom-node
    const { domRef } = this.props;
    mergeRefs(domRef)(dom);
  }

  public componentWillUnmount() {
    const { domRef } = this.props;
    mergeRefs(domRef)(null);
  }

  public render() {
    const { children, domRef, ...props } = this.props;

    const childrenElement = children;

    // 元素类型的，可以把要求渲染的 childrenProps 和原本的 props 合并
    if (React.isValidElement(childrenElement)) {
      return React.cloneElement(
        childrenElement,
        attachProps(childrenElement.props, props)
      );
    }

    return children;
  }
}

export const DomRef = forwardRef<HTMLElement, DomRefProps>((props, ref) => (
  <DomRefInner {...props} domRef={ref} />
));
