import {
  forwardRef,
  memo,
  useEffect,
  useImperativeHandle,
  useRef,
} from "react";
import { ModalPortal } from "./ModalPortal";
import { ModalProps } from "./types";

export const Modal = memo(
  forwardRef((props: ModalProps, ref: any) => {
    const { visible, children } = props;

    const id = useRef("");
    const refVisible = useRef(visible);

    const onClosed = () => {
      id.current = "";
      props.onClosed?.();
    };

    const show = () => {
      if (id.current) return;
      id.current = ModalPortal.show(children, {
        ...props,
        onClosed,
      });
    };

    const update = () => {
      if (!id.current) return;
      ModalPortal.update(id.current, { ...props, onClosed });
    };

    const dismiss = () => {
      if (!id.current) return;
      ModalPortal.dismiss(id.current);
      id.current = "";
    };

    useImperativeHandle(ref, () => ({
      show,
      dismiss,
    }));

    useEffect(() => {
      if (refVisible.current !== visible) {
        visible ? show() : dismiss();
        refVisible.current = visible;
      }
      update();
    });

    useEffect(() => {
      if (!ModalPortal.ref)
        throw new Error(
          "Can not use Modal component until ModalPortal is mounted"
        );
      if (visible) show();
      return dismiss;
    }, []);

    return null;
  })
);
