import React, { useEffect, useRef, useState, useCallback } from 'react';
import mermaid, { MermaidConfig } from 'mermaid';
import { SxProps } from '@mui/material/styles';
import { Box } from '@mui/material';
import { useResizeObserverAndMutationObserver } from './useAutoScrollToBottom';

const defaultMermaidConfig : MermaidConfig = {
  startOnLoad: true,
  securityLevel: 'loose',
  fontFamily: 'Fira Code',
};

interface MermaidProps {
  chart: string;
  sx?: SxProps;
  className?: string;
  mermaidConfig?: MermaidConfig;
}

const Mermaid: React.FC<MermaidProps> = (props: MermaidProps) => {
  const { chart, sx, className, mermaidConfig } = props;
  const [ visible, setVisible] = useState<boolean>(false);
  const containerRef = useRef<HTMLDivElement>(null);

  const checkVisible = useCallback(() => {
    if (containerRef.current) {
      const { width, height } = containerRef.current.getBoundingClientRect();
      if (width > 0 && height > 0) {
        setVisible(true);
      }
    }
  }, [containerRef, setVisible]);

  useEffect(() => {
    const renderMermaid = async () => {
      if (containerRef.current && visible && chart) {
        try {
          console.log("Rendering Mermaid");
          await mermaid.initialize(mermaidConfig || defaultMermaidConfig);
          await mermaid.run({ nodes: [containerRef.current] });
        } catch (e) {
          console.error("Mermaid render error:", e, containerRef.current);
        }
      }
    }
    renderMermaid();
  }, [containerRef, mermaidConfig, visible, chart]);

  // Observe container and TextField size, plus DOM changes
  useResizeObserverAndMutationObserver(containerRef, null, checkVisible);

  return <Box className={className || "Mermaid"} ref={containerRef} sx={{
    display: "flex",
    flexGrow: 1,
    ...sx
  }}>
    {chart}
  </Box>;
};

export {
  Mermaid
};