#!/usr/bin/env python
"""Unified renderer for Mermaid diagrams that works without external dependencies.

This module provides functions to generate HTML files from Mermaid diagram
code using pure browser-based rendering without requiring Node.js or external API calls.
"""

import os
from typing import Any, Dict, Optional


def generate_html_with_mermaid(
    mermaid_code: str, model_name: str, config: Optional[Dict[str, Any]] = None
) -> str:
    """Generate an HTML file with embedded Mermaid diagram.

    Args:
        mermaid_code: The Mermaid diagram code as a string
        model_name: Name of the model for the diagram title
        config: Optional configuration dictionary

    Returns:
        HTML content as a string
    """
    if config is None:
        config = {}

    # Get theme from config
    theme = config.get("mermaid", {}).get("theme", "neutral")

    # Get interactive mode setting
    interactive = config.get("mermaid", {}).get("interactive", True)

    # Generate the HTML
    return generate_html(mermaid_code, model_name, theme, interactive)


def generate_html(
    mermaid_code: str, model_name: str, theme: str = "neutral", interactive: bool = True
) -> str:
    """Generate HTML content that renders a Mermaid diagram using client-side JavaScript.

    Args:
        mermaid_code: The Mermaid diagram code
        model_name: Name of the model for the diagram title
        theme: Mermaid theme to use
        interactive: Whether to include interactive features (buttons, etc.)

    Returns:
        HTML content as a string
    """
    if interactive:
        html_template = rf"""<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>{model_name} Data Model</title>
    <script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
    <style>
        body {{ font-family: Arial, sans-serif; margin: 0; padding: 20px; background-color: #f5f5f5; }}
        #container {{ background-color: white; padding: 20px; border-radius: 5px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }}
        h1 {{ color: #333; }}
        .mermaid {{ overflow: auto; }}
        .buttons {{ margin-top: 20px; text-align: center; }}
        button {{ padding: 8px 16px; margin: 0 5px; background-color: #4b6bbd; color: white; 
                 border: none; border-radius: 4px; cursor: pointer; }}
        button:hover {{ background-color: #3a559d; }}
        .footer {{ margin-top: 20px; text-align: center; color: #666; font-size: 0.9em; }}
        #codeArea {{ display: none; }}
    </style>
    <script>
        mermaid.initialize({{
            startOnLoad: true,
            theme: '{theme}',
            securityLevel: 'loose',
            flowchart: {{ htmlLabels: true }},
            er: {{
                diagramPadding: 20,
                layoutDirection: 'LR',
                minEntityWidth: 120,
                minEntityHeight: 75,
                entityPadding: 15
            }}
        }});
    </script>
</head>
<body>
    <div id="container">
        <h1>{model_name} Data Model</h1>
        <div class="mermaid">
{mermaid_code}
        </div>
        
        <div class="buttons">
            <button onclick="saveSvg()">Download as SVG</button>
            <button onclick="savePng()">Download as PNG</button>
            <button onclick="copyMermaidCode()">Copy Mermaid Code</button>
        </div>
        
        <div class="footer">
            <p>Generated by dbt-erd v1.0.0</p>
        </div>
    </div>
    
    <!-- Hidden textarea for copying -->
    <textarea id="codeArea">{mermaid_code}</textarea>
    
    <script>
        function copyMermaidCode() {{
            const codeArea = document.getElementById('codeArea');
            codeArea.style.display = 'block';
            codeArea.select();
            document.execCommand('copy');
            codeArea.style.display = 'none';
            alert('Mermaid code copied to clipboard!');
        }}
    
        function saveSvg() {{
            // Get the SVG element
            setTimeout(() => {{
                const svgElement = document.querySelector('.mermaid svg');
                if (!svgElement) {{
                    alert('SVG not found. Please wait for diagram to render.');
                    return;
                }}
                
                // Get SVG source
                const serializer = new XMLSerializer();
                let source = serializer.serializeToString(svgElement);
                
                // Add namespaces
                if (!source.match(/^<svg[^>]+xmlns="http:\/\/www\.w3\.org\/2000\/svg"/)) {{
                    source = source.replace(/^<svg/, '<svg xmlns="http://www.w3.org/2000/svg"');
                }}
                
                // Convert SVG source to URI data scheme
                const svgBlob = new Blob([source], {{type:"image/svg+xml;charset=utf-8"}});
                const svgUrl = URL.createObjectURL(svgBlob);
                
                // Create download link
                const downloadLink = document.createElement("a");
                downloadLink.href = svgUrl;
                downloadLink.download = "{model_name}_diagram.svg";
                document.body.appendChild(downloadLink);
                downloadLink.click();
                document.body.removeChild(downloadLink);
            }}, 1000); // Wait for diagram to render
        }}
        
        function savePng() {{
            // Get the SVG element
            setTimeout(() => {{
                const svgElement = document.querySelector('.mermaid svg');
                if (!svgElement) {{
                    alert('SVG not found. Please wait for diagram to render.');
                    return;
                }}
                
                // Create a canvas element
                const canvas = document.createElement('canvas');
                const ctx = canvas.getContext('2d');
                
                // Get SVG dimensions
                const svgRect = svgElement.getBoundingClientRect();
                canvas.width = svgRect.width;
                canvas.height = svgRect.height;
                
                // Create image from SVG
                const img = new Image();
                const serializer = new XMLSerializer();
                const svgStr = serializer.serializeToString(svgElement);
                img.src = 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(svgStr)));
                
                img.onload = function() {{
                    // Draw image to canvas
                    ctx.drawImage(img, 0, 0);
                    
                    // Convert to PNG
                    try {{
                        const pngUrl = canvas.toDataURL('image/png');
                        
                        // Create download link
                        const downloadLink = document.createElement('a');
                        downloadLink.href = pngUrl;
                        downloadLink.download = '{model_name}_diagram.png';
                        document.body.appendChild(downloadLink);
                        downloadLink.click();
                        document.body.removeChild(downloadLink);
                    }} catch(e) {{
                        console.error(e);
                        alert('Error creating PNG. This might be due to CORS restrictions if opening the file directly.');
                    }}
                }};
            }}, 1000); // Wait for diagram to render
        }}
    </script>
</body>
</html>
"""
    else:
        # Simple version without interactive features
        html_template = f"""<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>{model_name} Data Model</title>
    <script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
    <style>
        body {{ font-family: Arial, sans-serif; margin: 0; padding: 0; }}
        h1 {{ color: #333; padding: 20px; margin: 0; }}
        .mermaid {{ width: 100%; padding: 20px; }}
    </style>
    <script>
        mermaid.initialize({{
            startOnLoad: true,
            theme: '{theme}',
            er: {{
                diagramPadding: 20,
                layoutDirection: 'LR',
                minEntityWidth: 120,
                minEntityHeight: 75,
                entityPadding: 15
            }}
        }});
    </script>
</head>
<body>
    <h1>{model_name} Data Model</h1>
    <div class="mermaid">
{mermaid_code}
    </div>
</body>
</html>
"""
    return html_template


def save_mermaid_outputs(
    mermaid_code: str, model_name: str, output_dir: str, config: Dict[str, Any]
) -> Dict[str, str]:
    """Save Mermaid diagram in multiple formats based on configuration.

    Args:
        mermaid_code: The Mermaid diagram code
        model_name: Name of the model
        output_dir: Directory to save output files
        config: Configuration dictionary

    Returns:
        Dictionary of output file paths
    """
    outputs = config.get("mermaid", {}).get(
        "outputs",
        {
            "mmd": True,
            "html": True,
        },
    )

    result_files = {}

    # Ensure output directory exists
    os.makedirs(output_dir, exist_ok=True)

    # Save .mmd file
    if outputs.get("mmd", True):
        mmd_path = os.path.join(output_dir, f"{model_name}_model.mmd")
        with open(mmd_path, "w", encoding="utf-8") as f:
            f.write(mermaid_code)
        result_files["mmd"] = mmd_path

    # Generate HTML
    if outputs.get("html", True):
        html_path = os.path.join(output_dir, f"{model_name}_model.html")
        html_content = generate_html_with_mermaid(mermaid_code, model_name, config)
        with open(html_path, "w", encoding="utf-8") as f:
            f.write(html_content)
        result_files["html"] = html_path

    return result_files
