/* eslint-disable @typescript-eslint/no-unnecessary-condition */
"use client";

import { useCallback, useEffect, useRef, useState } from "react";
import mermaid from "mermaid";
import DOMPurify from "dompurify";

interface MermaidViewerProps {
  diagram: string;
  className?: string;
  onNodeClick?: (nodeId: string) => void;
}

export function MermaidViewer({
  diagram,
  className = "",
  onNodeClick,
}: MermaidViewerProps): React.JSX.Element {
  const containerRef = useRef<HTMLDivElement>(null);
  const [error, setError] = useState<string | null>(null);
  const [isLoading, setIsLoading] = useState(true);

  const renderDiagram = useCallback(async () => {
    if (!containerRef.current || !diagram) {
      setIsLoading(false);
      return;
    }

    setIsLoading(true);
    setError(null);

    try {
      // Initialize mermaid with theme based on document
      const isDark = document.documentElement.classList.contains("dark");
      mermaid.initialize({
        startOnLoad: false,
        theme: isDark ? "dark" : "default",
        flowchart: {
          useMaxWidth: true,
          htmlLabels: false,
          curve: "basis",
        },
        securityLevel: "strict",
      });

      // Generate unique ID for this render
      const id = `mermaid-${String(Date.now())}`;

      // Render the diagram
      const { svg } = await mermaid.render(id, diagram);

      // Sanitize SVG output with DOMPurify for defense-in-depth
      // Configure DOMPurify to allow SVG elements but remove scripts and dangerous attributes
      const sanitizedSvg = DOMPurify.sanitize(svg, {
        USE_PROFILES: { svg: true, svgFilters: true },
        ADD_TAGS: ["use"], // Allow SVG use elements
        FORBID_TAGS: ["script", "iframe", "object", "embed", "base"],
        FORBID_ATTR: [
          "onerror",
          "onload",
          "onclick",
          "onmouseover",
          "onfocus",
          "onblur",
          "onchange",
          "oninput",
        ],
      });

      const container = containerRef.current;
      if (container) {
        container.innerHTML = sanitizedSvg;

        // Add click handlers to nodes if callback provided
        if (onNodeClick) {
          const nodes = container.querySelectorAll(".node");
          nodes.forEach((node) => {
            node.addEventListener("click", () => {
              const nodeId = node.id.replace(/^flowchart-/, "").replace(/-\d+$/, "");
              if (nodeId) {
                onNodeClick(nodeId);
              }
            });
            (node as HTMLElement).style.cursor = "pointer";
          });
        }
      }
    } catch (err) {
      // Log detailed error for debugging but don't expose raw source/messages to the UI
      console.error("Mermaid rendering failed:", err);
      setError("Diagram rendering failed. Please check the diagram syntax and try again.");
    } finally {
      setIsLoading(false);
    }
  }, [diagram, onNodeClick]);

  useEffect(() => {
    void renderDiagram();
  }, [renderDiagram]);

  // Re-render on theme change
  useEffect(() => {
    const observer = new MutationObserver((mutations) => {
      mutations.forEach((mutation) => {
        if (mutation.attributeName === "class") {
          void renderDiagram();
        }
      });
    });

    observer.observe(document.documentElement, { attributes: true });

    return (): void => {
      observer.disconnect();
    };
  }, [renderDiagram]);

  if (!diagram) {
    return (
      <div className={`flex items-center justify-center p-8 text-gray-500 ${className}`}>
        No diagram data available
      </div>
    );
  }

  if (error) {
    return (
      <div className={`flex flex-col items-center justify-center p-8 ${className}`}>
        <div className="text-red-500 mb-2">Diagram rendering failed</div>
        <div className="text-sm text-gray-500">Please check the diagram syntax and try again.</div>
      </div>
    );
  }

  return (
    <div className={`relative ${className}`}>
      {isLoading && (
        <div className="absolute inset-0 flex items-center justify-center bg-white/50 dark:bg-gray-900/50">
          <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500" />
        </div>
      )}
      <div
        ref={containerRef}
        className="mermaid-container overflow-auto"
        style={{ minHeight: "200px" }}
      />
    </div>
  );
}
