import { FloatingToolbar, CopyAction, FullscreenAction } from './chunk-KNEQRUBA.mjs';
import { __name } from './chunk-N2XQF2OL.mjs';
import { useState, useRef, useEffect, useCallback } from 'react';
import { useResolvedTheme } from '@djangocfg/ui-core/hooks';
import { createPortal } from 'react-dom';
import { ZoomOut, RotateCcw, ZoomIn, X } from 'lucide-react';
import { useControls, TransformWrapper, TransformComponent } from 'react-zoom-pan-pinch';
import { Button } from '@djangocfg/ui-core/components';
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
import mermaid from 'mermaid';

// src/tools/Mermaid/utils/mermaid-helpers.ts
var applyMermaidTextColors = /* @__PURE__ */ __name((container, textColor) => {
  const svgElement = container.querySelector("svg");
  if (svgElement) {
    svgElement.querySelectorAll("text").forEach((el) => {
      el.style.fill = textColor;
    });
    svgElement.querySelectorAll(".nodeLabel, .edgeLabel").forEach((el) => {
      el.style.color = textColor;
    });
  }
}, "applyMermaidTextColors");
function ZoomControls() {
  const { zoomIn, zoomOut, resetTransform } = useControls();
  return /* @__PURE__ */ jsxs("div", { className: "absolute bottom-4 left-1/2 -translate-x-1/2 flex gap-2 z-10", children: [
    /* @__PURE__ */ jsx(Button, { variant: "secondary", size: "icon", onClick: () => zoomOut(), children: /* @__PURE__ */ jsx(ZoomOut, { className: "h-4 w-4" }) }),
    /* @__PURE__ */ jsx(Button, { variant: "secondary", size: "icon", onClick: () => resetTransform(), children: /* @__PURE__ */ jsx(RotateCcw, { className: "h-4 w-4" }) }),
    /* @__PURE__ */ jsx(Button, { variant: "secondary", size: "icon", onClick: () => zoomIn(), children: /* @__PURE__ */ jsx(ZoomIn, { className: "h-4 w-4" }) })
  ] });
}
__name(ZoomControls, "ZoomControls");
var MermaidFullscreenModal = /* @__PURE__ */ __name(({
  isOpen,
  svgContent,
  isVertical,
  theme,
  fullscreenRef,
  onClose,
  onBackdropClick
}) => {
  const [initialScale, setInitialScale] = useState(null);
  const [openSeq, setOpenSeq] = useState(0);
  useEffect(() => {
    if (!isOpen) {
      setInitialScale(null);
      return;
    }
    setOpenSeq((n) => n + 1);
    let cancelled = false;
    let attempts = 0;
    const tick = /* @__PURE__ */ __name(() => {
      if (cancelled) return;
      attempts += 1;
      const svg = fullscreenRef.current?.querySelector("svg");
      const bbox = svg?.getBoundingClientRect();
      if (svg && bbox && bbox.width > 1 && bbox.height > 1) {
        const targetW = window.innerWidth * 0.9;
        const targetH = window.innerHeight * 0.9;
        const fit = Math.min(targetW / bbox.width, targetH / bbox.height);
        setInitialScale(Math.max(1, Math.min(fit, 6)));
        return;
      }
      if (attempts < 30) {
        requestAnimationFrame(tick);
      } else {
        setInitialScale(1);
      }
    }, "tick");
    requestAnimationFrame(tick);
    return () => {
      cancelled = true;
    };
  }, [isOpen, svgContent, fullscreenRef]);
  useEffect(() => {
    if (isOpen && fullscreenRef.current) {
      const getCSSVariable = /* @__PURE__ */ __name((variable) => {
        if (typeof document === "undefined") return "";
        const value = getComputedStyle(document.documentElement).getPropertyValue(variable).trim();
        return value ? `hsl(${value})` : "";
      }, "getCSSVariable");
      const textColor = theme === "dark" ? getCSSVariable("--foreground") || "hsl(0 0% 90%)" : getCSSVariable("--foreground") || "hsl(222.2 84% 4.9%)";
      applyMermaidTextColors(fullscreenRef.current, textColor);
    }
  }, [isOpen, theme, isVertical, fullscreenRef, svgContent]);
  useEffect(() => {
    if (!isOpen) return;
    const handleKeyDown = /* @__PURE__ */ __name((e) => {
      if (e.key === "Escape") onClose();
    }, "handleKeyDown");
    document.addEventListener("keydown", handleKeyDown);
    return () => document.removeEventListener("keydown", handleKeyDown);
  }, [isOpen, onClose]);
  if (!isOpen || typeof document === "undefined") return null;
  const transformInitialScale = initialScale ?? 1;
  const transformKey = `${openSeq}-${initialScale ?? "pending"}`;
  return createPortal(
    /* @__PURE__ */ jsxs(
      "div",
      {
        className: "fixed inset-0 z-9999 bg-background/95 backdrop-blur-sm",
        onClick: onBackdropClick,
        children: [
          /* @__PURE__ */ jsx(
            Button,
            {
              variant: "ghost",
              size: "icon",
              className: "absolute top-4 right-4 z-10",
              onClick: onClose,
              children: /* @__PURE__ */ jsx(X, { className: "h-5 w-5" })
            }
          ),
          /* @__PURE__ */ jsxs(
            TransformWrapper,
            {
              initialScale: transformInitialScale,
              minScale: 0.1,
              maxScale: 10,
              centerOnInit: true,
              wheel: { step: 0.1 },
              pinch: { step: 5 },
              doubleClick: { mode: "reset" },
              children: [
                /* @__PURE__ */ jsx(ZoomControls, {}),
                /* @__PURE__ */ jsx(
                  TransformComponent,
                  {
                    wrapperStyle: {
                      width: "100%",
                      height: "100%"
                    },
                    contentStyle: {
                      width: "100%",
                      height: "100%",
                      display: "flex",
                      alignItems: "center",
                      justifyContent: "center"
                    },
                    children: /* @__PURE__ */ jsx(
                      "div",
                      {
                        ref: fullscreenRef,
                        className: "p-8",
                        dangerouslySetInnerHTML: { __html: svgContent },
                        onClick: (e) => e.stopPropagation()
                      }
                    )
                  }
                )
              ]
            },
            transformKey
          )
        ]
      }
    ),
    document.body
  );
}, "MermaidFullscreenModal");
function useMermaidFullscreen() {
  const [isFullscreen, setIsFullscreen] = useState(false);
  const fullscreenRef = useRef(null);
  const openFullscreen = /* @__PURE__ */ __name(() => setIsFullscreen(true), "openFullscreen");
  const closeFullscreen = /* @__PURE__ */ __name(() => setIsFullscreen(false), "closeFullscreen");
  const handleBackdropClick = /* @__PURE__ */ __name((e) => {
    if (e.target === e.currentTarget) {
      closeFullscreen();
    }
  }, "handleBackdropClick");
  useEffect(() => {
    const handleEscKey = /* @__PURE__ */ __name((event) => {
      if (event.key === "Escape" && isFullscreen) {
        closeFullscreen();
      }
    }, "handleEscKey");
    if (isFullscreen) {
      document.addEventListener("keydown", handleEscKey);
      document.body.style.overflow = "hidden";
    }
    return () => {
      document.removeEventListener("keydown", handleEscKey);
      document.body.style.overflow = "unset";
    };
  }, [isFullscreen]);
  return {
    isFullscreen,
    fullscreenRef,
    openFullscreen,
    closeFullscreen,
    handleBackdropClick
  };
}
__name(useMermaidFullscreen, "useMermaidFullscreen");
function useMermaidCleanup() {
  const cleanupMermaidErrors = useCallback(() => {
    if (typeof document === "undefined") return;
    document.querySelectorAll('[id^="mermaid-"]').forEach((node) => {
      if (node.parentNode === document.body) {
        node.remove();
      }
    });
    document.querySelectorAll('[id^="d"]').forEach((node) => {
      if (node.parentNode === document.body && node.id.match(/^d\d+$/)) {
        node.remove();
      }
    });
    document.querySelectorAll("body > svg").forEach((node) => {
      if (node.getAttribute("aria-roledescription") || node.classList.contains("mermaid") || node.querySelector(".mermaid") || node.id?.includes("mermaid")) {
        node.remove();
      }
    });
    document.querySelectorAll("body > div").forEach((node) => {
      const text = node.textContent || "";
      if (text.includes("Syntax error in text") || text.includes("mermaid version") || node.id?.startsWith("mermaid-") || node.id?.startsWith("d") && node.id.match(/^d\d+$/)) {
        node.remove();
      }
    });
    document.querySelectorAll("body > pre").forEach((node) => {
      const text = node.textContent || "";
      if (text.includes("Syntax error") || text.includes("mermaid")) {
        node.remove();
      }
    });
  }, []);
  useEffect(() => {
    return () => {
      cleanupMermaidErrors();
    };
  }, [cleanupMermaidErrors]);
  return { cleanupMermaidErrors };
}
__name(useMermaidCleanup, "useMermaidCleanup");
function useMermaidValidation() {
  const isMermaidCodeComplete = useCallback((code) => {
    if (!code || code.trim().length === 0) return false;
    const trimmed = code.trim();
    const lines = trimmed.split("\n");
    if (lines.length < 2) return false;
    const lastLine = lines[lines.length - 1].trim();
    if (lastLine.match(/-->?\s*$/)) return false;
    if (lastLine.match(/-->\|[^|]*\|\s*$/)) return false;
    if (lastLine.match(/[\[({]\s*$/)) return false;
    return true;
  }, []);
  return { isMermaidCodeComplete };
}
__name(useMermaidValidation, "useMermaidValidation");

// src/tools/Mermaid/hooks/useMermaidRenderer.ts
var applyMermaidTextColors2 = /* @__PURE__ */ __name((container, textColor) => {
  const svgElement = container.querySelector("svg");
  if (svgElement) {
    svgElement.querySelectorAll("text").forEach((el) => {
      el.style.fill = textColor;
    });
    svgElement.querySelectorAll(".nodeLabel, .edgeLabel").forEach((el) => {
      el.style.color = textColor;
    });
  }
}, "applyMermaidTextColors");
var isVerticalDiagram = /* @__PURE__ */ __name((svgElement) => {
  const viewBox = svgElement.getAttribute("viewBox");
  if (viewBox) {
    const [, , width, height] = viewBox.split(" ").map(Number);
    return height > width * 1.5;
  }
  const bbox = svgElement.getBBox?.();
  if (bbox) {
    return bbox.height > bbox.width * 1.5;
  }
  return false;
}, "isVerticalDiagram");
function useMermaidRenderer({ chart, theme, isCompact = false }) {
  const mermaidRef = useRef(null);
  const renderTimerRef = useRef(null);
  const [svgContent, setSvgContent] = useState("");
  const [isVertical, setIsVertical] = useState(false);
  const [isRendering, setIsRendering] = useState(false);
  const { isMermaidCodeComplete } = useMermaidValidation();
  const { cleanupMermaidErrors } = useMermaidCleanup();
  useEffect(() => {
    const getCSSVariable = /* @__PURE__ */ __name((variable) => {
      if (typeof document === "undefined") return "";
      const value = getComputedStyle(document.documentElement).getPropertyValue(variable).trim();
      if (!value) return "";
      if (value.startsWith("#") || value.startsWith("rgb") || value.startsWith("hsl(")) {
        return value;
      }
      return `hsl(${value})`;
    }, "getCSSVariable");
    const diagramFontSize = isCompact ? "12px" : "14px";
    const themeVariables = theme === "dark" ? {
      primaryColor: getCSSVariable("--primary") || "hsl(221.2 83.2% 53.3%)",
      primaryTextColor: getCSSVariable("--foreground") || "hsl(210 40% 98%)",
      primaryBorderColor: getCSSVariable("--primary") || "hsl(221.2 83.2% 53.3%)",
      secondaryColor: getCSSVariable("--muted") || "hsl(217.2 32.6% 17.5%)",
      secondaryTextColor: getCSSVariable("--foreground") || "hsl(210 40% 98%)",
      secondaryBorderColor: getCSSVariable("--border") || "hsl(217.2 32.6% 27.5%)",
      tertiaryColor: getCSSVariable("--accent") || "hsl(217.2 32.6% 20%)",
      tertiaryTextColor: getCSSVariable("--foreground") || "hsl(210 40% 98%)",
      tertiaryBorderColor: getCSSVariable("--border") || "hsl(217.2 32.6% 27.5%)",
      mainBkg: getCSSVariable("--card") || "hsl(222.2 84% 8%)",
      textColor: getCSSVariable("--foreground") || "hsl(210 40% 98%)",
      nodeBorder: getCSSVariable("--border") || "hsl(217.2 32.6% 27.5%)",
      nodeTextColor: getCSSVariable("--foreground") || "hsl(210 40% 98%)",
      secondBkg: getCSSVariable("--muted") || "hsl(217.2 32.6% 17.5%)",
      lineColor: getCSSVariable("--primary") || "hsl(221.2 83.2% 53.3%)",
      edgeLabelBackground: getCSSVariable("--card") || "hsl(222.2 84% 8%)",
      clusterBkg: getCSSVariable("--muted") || "hsl(217.2 32.6% 12%)",
      clusterBorder: getCSSVariable("--primary") || "hsl(221.2 83.2% 53.3%)",
      background: getCSSVariable("--background") || "hsl(222.2 84% 4.9%)",
      labelBackground: getCSSVariable("--card") || "hsl(222.2 84% 8%)",
      labelTextColor: getCSSVariable("--foreground") || "hsl(210 40% 98%)",
      errorBkgColor: getCSSVariable("--destructive") || "hsl(0 62.8% 30.6%)",
      errorTextColor: "hsl(210 40% 98%)",
      fontSize: diagramFontSize,
      fontFamily: "Inter, system-ui, sans-serif"
    } : {
      primaryColor: getCSSVariable("--primary") || "hsl(221.2 83.2% 53.3%)",
      primaryTextColor: getCSSVariable("--foreground") || "hsl(222.2 84% 4.9%)",
      primaryBorderColor: getCSSVariable("--primary") || "hsl(221.2 83.2% 53.3%)",
      secondaryColor: getCSSVariable("--secondary") || "hsl(210 40% 96.1%)",
      secondaryTextColor: getCSSVariable("--foreground") || "hsl(222.2 84% 4.9%)",
      secondaryBorderColor: getCSSVariable("--border") || "hsl(214.3 31.8% 91.4%)",
      tertiaryColor: getCSSVariable("--muted") || "hsl(210 40% 96.1%)",
      tertiaryTextColor: getCSSVariable("--foreground") || "hsl(222.2 84% 4.9%)",
      tertiaryBorderColor: getCSSVariable("--border") || "hsl(214.3 31.8% 91.4%)",
      mainBkg: getCSSVariable("--card") || "hsl(0 0% 100%)",
      textColor: getCSSVariable("--foreground") || "hsl(222.2 84% 4.9%)",
      nodeBorder: getCSSVariable("--border") || "hsl(214.3 31.8% 91.4%)",
      nodeTextColor: getCSSVariable("--foreground") || "hsl(222.2 84% 4.9%)",
      secondBkg: getCSSVariable("--muted") || "hsl(210 40% 96.1%)",
      lineColor: getCSSVariable("--primary") || "hsl(221.2 83.2% 53.3%)",
      edgeLabelBackground: getCSSVariable("--card") || "hsl(0 0% 100%)",
      clusterBkg: getCSSVariable("--accent") || "hsl(210 40% 98%)",
      clusterBorder: getCSSVariable("--primary") || "hsl(221.2 83.2% 53.3%)",
      background: getCSSVariable("--background") || "hsl(0 0% 100%)",
      labelBackground: getCSSVariable("--card") || "hsl(0 0% 100%)",
      labelTextColor: getCSSVariable("--foreground") || "hsl(222.2 84% 4.9%)",
      errorBkgColor: getCSSVariable("--destructive") || "hsl(0 84.2% 60.2%)",
      errorTextColor: "hsl(210 40% 98%)",
      fontSize: diagramFontSize,
      fontFamily: "Inter, system-ui, sans-serif"
    };
    mermaid.initialize({
      startOnLoad: false,
      theme: "base",
      securityLevel: "loose",
      suppressErrorRendering: true,
      // Prevent mermaid from appending errors to body
      fontFamily: "Inter, system-ui, sans-serif",
      flowchart: {
        useMaxWidth: true,
        htmlLabels: true,
        curve: "basis"
      },
      themeVariables
    });
    const renderChart = /* @__PURE__ */ __name(async () => {
      if (!mermaidRef.current || !chart) return;
      if (!isMermaidCodeComplete(chart)) {
        setIsRendering(true);
        return;
      }
      try {
        setIsRendering(true);
        if (mermaidRef.current) {
          mermaidRef.current.innerHTML = "";
        }
        const id = `mermaid-${Math.random().toString(36).substring(2, 9)}`;
        const { svg } = await mermaid.render(id, chart);
        if (mermaidRef.current) {
          const textColor = theme === "dark" ? getCSSVariable("--foreground") || "hsl(0 0% 90%)" : getCSSVariable("--foreground") || "hsl(222.2 84% 4.9%)";
          const processedSvg = svg.replace(
            /<svg /,
            `<svg style="--mermaid-text-color: ${textColor};" `
          );
          mermaidRef.current.innerHTML = processedSvg;
          setSvgContent(processedSvg);
          applyMermaidTextColors2(mermaidRef.current, textColor);
          const svgElement = mermaidRef.current.querySelector("svg");
          if (svgElement) {
            svgElement.style.maxWidth = "100%";
            svgElement.style.height = "auto";
            svgElement.style.display = "block";
            setIsVertical(isVerticalDiagram(svgElement));
          }
        }
        setIsRendering(false);
      } catch (error) {
        console.error("Mermaid rendering error:", error);
        setIsRendering(false);
        cleanupMermaidErrors();
        if (mermaidRef.current) {
          mermaidRef.current.innerHTML = `
                        <div class="p-4 text-destructive bg-destructive/10 border border-destructive/20 rounded-sm">
                            <p class="font-semibold">Mermaid Diagram Error</p>
                            <p class="text-sm">${error instanceof Error ? error.message : "Unknown error"}</p>
                        </div>
                    `;
        }
      }
    }, "renderChart");
    if (renderTimerRef.current) {
      clearTimeout(renderTimerRef.current);
    }
    renderTimerRef.current = setTimeout(() => {
      renderChart();
    }, 500);
    return () => {
      if (renderTimerRef.current) {
        clearTimeout(renderTimerRef.current);
      }
    };
  }, [chart, theme, isCompact, isMermaidCodeComplete, cleanupMermaidErrors]);
  return {
    mermaidRef,
    svgContent,
    isVertical,
    isRendering
  };
}
__name(useMermaidRenderer, "useMermaidRenderer");
var Mermaid = /* @__PURE__ */ __name(({
  chart,
  className = "",
  isCompact = false,
  fullscreen = true,
  scrollIsolation = false
}) => {
  const containerRef = useRef(null);
  const theme = useResolvedTheme();
  const { mermaidRef, svgContent, isVertical, isRendering } = useMermaidRenderer({
    chart,
    theme,
    isCompact
  });
  const {
    isFullscreen,
    fullscreenRef,
    openFullscreen,
    closeFullscreen,
    handleBackdropClick
  } = useMermaidFullscreen();
  return /* @__PURE__ */ jsxs(Fragment, { children: [
    /* @__PURE__ */ jsxs("div", { ref: containerRef, className: `relative ${className}`, children: [
      /* @__PURE__ */ jsx(
        "div",
        {
          ref: mermaidRef,
          className: "flex justify-center items-center",
          style: { isolation: "isolate" }
        }
      ),
      isRendering && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "animate-spin rounded-full h-6 w-6 border-b-2 border-primary" }) }),
      svgContent && !isRendering && /* @__PURE__ */ jsxs(FloatingToolbar, { containerRef, scrollIsolation, children: [
        /* @__PURE__ */ jsx(CopyAction, { value: chart, title: "Copy source" }),
        fullscreen && /* @__PURE__ */ jsx(FullscreenAction, { onToggle: openFullscreen, title: "Fullscreen" })
      ] })
    ] }),
    fullscreen && /* @__PURE__ */ jsx(
      MermaidFullscreenModal,
      {
        isOpen: isFullscreen,
        svgContent,
        isVertical,
        theme,
        chart,
        fullscreenRef,
        onClose: closeFullscreen,
        onBackdropClick: handleBackdropClick
      }
    )
  ] });
}, "Mermaid");
var Mermaid_client_default = Mermaid;

export { Mermaid_client_default as default };
//# sourceMappingURL=Mermaid.client-NL4SVR7F.mjs.map
//# sourceMappingURL=Mermaid.client-NL4SVR7F.mjs.map