import React, { useEffect, useState, useRef } from "react";
import mermaid from "mermaid";
import { Download, Info } from "@phosphor-icons/react";
import { Button } from "@/components/ui/button";

interface MermaidProps {
    chart: string;
}

const Mermaid: React.FC<MermaidProps> = ({ chart }) => {
    const [mermaidError, setMermaidError] = useState<string | null>(null);
    const [mermaidId] = useState(`mermaid-chart-${Math.random().toString(12).substring(7)}`);
    const elementRef = useRef<HTMLDivElement>(null);

    useEffect(() => {
        mermaid.initialize({
            startOnLoad: false,
        });

        mermaid.parseError = (error) => {
            console.error("Mermaid errors:", error);
            // Extract error message from error object
            // Parse error message safely
            let errorMessage;
            try {
                errorMessage = typeof error === "string" ? JSON.parse(error) : error;
            } catch (e) {
                errorMessage = error?.toString() || "Unknown error";
            }

            console.log("Mermaid error message:", errorMessage);

            if (errorMessage.str !== "element is null") {
                setMermaidError(
                    "Something went wrong while rendering the diagram. Please try again later or downvote the message if the issue persists.",
                );
            } else {
                setMermaidError(null);
            }
        };

        mermaid.contentLoaded();
    }, []);

    const handleExport = async () => {
        if (!elementRef.current) return;

        try {
            // Get SVG element
            const svgElement = elementRef.current.querySelector("svg");
            if (!svgElement) throw new Error("No SVG found");

            // Get SVG viewBox dimensions
            const viewBox = svgElement.getAttribute("viewBox")?.split(" ").map(Number) || [
                0, 0, 0, 0,
            ];
            const [, , viewBoxWidth, viewBoxHeight] = viewBox;

            // Create canvas with viewBox dimensions
            const canvas = document.createElement("canvas");
            const scale = 2; // For better resolution
            canvas.width = viewBoxWidth * scale;
            canvas.height = viewBoxHeight * scale;
            const ctx = canvas.getContext("2d");
            if (!ctx) throw new Error("Failed to get canvas context");

            // Convert SVG to data URL
            const svgData = new XMLSerializer().serializeToString(svgElement);
            const svgBlob = new Blob([svgData], { type: "image/svg+xml;charset=utf-8" });
            const svgUrl = URL.createObjectURL(svgBlob);

            // Create and load image
            const img = new Image();
            img.src = svgUrl;

            await new Promise((resolve, reject) => {
                img.onload = () => {
                    // Scale context for better resolution
                    ctx.scale(scale, scale);
                    ctx.drawImage(img, 0, 0, viewBoxWidth, viewBoxHeight);

                    canvas.toBlob((blob) => {
                        if (!blob) {
                            reject(new Error("Failed to create blob"));
                            return;
                        }

                        const url = URL.createObjectURL(blob);
                        const a = document.createElement("a");
                        a.href = url;
                        a.download = `mermaid-diagram-${Date.now()}.png`;
                        a.click();

                        // Cleanup
                        URL.revokeObjectURL(url);
                        URL.revokeObjectURL(svgUrl);
                        resolve(true);
                    }, "image/png");
                };

                img.onerror = () => reject(new Error("Failed to load SVG"));
            });
        } catch (error) {
            console.error("Error exporting diagram:", error);
            setMermaidError("Failed to export diagram");
        }
    };

    useEffect(() => {
        if (elementRef.current) {
            elementRef.current.removeAttribute("data-processed");

            mermaid
                .run({
                    nodes: [elementRef.current],
                })
                .then(() => {
                    setMermaidError(null);
                })
                .catch((error) => {
                    let errorMessage;
                    try {
                        errorMessage = typeof error === "string" ? JSON.parse(error) : error;
                    } catch (e) {
                        errorMessage = error?.toString() || "Unknown error";
                    }

                    console.log("Mermaid error message:", errorMessage);

                    if (errorMessage.str !== "element is null") {
                        setMermaidError(
                            "Something went wrong while rendering the diagram. Please try again later or downvote the message if the issue persists.",
                        );
                    } else {
                        setMermaidError(null);
                    }
                });
        }
    }, [chart]);

    return (
        <div>
            {mermaidError ? (
                <>
                    <div className="flex items-center gap-2 bg-red-100 border border-red-500 rounded-md p-1 mt-3 text-red-900 text-sm">
                        <Info className="w-12 h-12" />
                        <span>{mermaidError}</span>
                    </div>
                    <code className="block bg-secondary text-secondary-foreground p-4 mt-3 rounded-lg font-mono text-sm whitespace-pre-wrap overflow-x-auto max-h-[400px] border border-gray-200">
                        {chart}
                    </code>
                </>
            ) : (
                <div
                    id={mermaidId}
                    ref={elementRef}
                    className="mermaid"
                    style={{
                        width: "auto",
                        height: "auto",
                        boxSizing: "border-box",
                        overflow: "auto",
                    }}
                >
                    {chart}
                </div>
            )}
            {!mermaidError && (
                <Button onClick={handleExport} variant={"secondary"} className="mt-3">
                    <Download className="w-5 h-5" />
                    Export as PNG
                </Button>
            )}
        </div>
    );
};

export default Mermaid;
