"""
Graph visualization export for dependency graphs.

Exports DependencyGraph to DOT (Graphviz) and Mermaid diagram formats.
"""

from markitect.prompts.dependencies.models import DependencyGraph, EdgeType


# Edge type to style mappings
_DOT_EDGE_STYLES = {
    EdgeType.REQUIRES: 'style="solid"',
    EdgeType.GENERATES: 'style="dashed"',
    EdgeType.INCLUDES: 'style="dotted"',
}

_MERMAID_EDGE_STYLES = {
    EdgeType.REQUIRES: "-->",
    EdgeType.GENERATES: "-.->",
    EdgeType.INCLUDES: "==>",
}


class GraphExporter:
    """Export DependencyGraph to DOT and Mermaid formats."""

    @staticmethod
    def to_dot(graph: DependencyGraph, title: str = "Dependencies") -> str:
        """
        Export dependency graph to Graphviz DOT format.

        Args:
            graph: DependencyGraph to export
            title: Graph title

        Returns:
            DOT format string
        """
        lines = [
            f'digraph "{title}" {{',
            "  rankdir=LR;",
            f'  label="{title}";',
            "  node [shape=box];",
        ]

        # Add nodes
        for node in sorted(graph.nodes):
            safe_id = node.replace("-", "_")
            lines.append(f'  {safe_id} [label="{node}"];')

        # Add edges
        for source in sorted(graph.nodes):
            for target in sorted(graph.get_successors(source)):
                edge_type = graph.get_edge_type(source, target)
                style = _DOT_EDGE_STYLES.get(edge_type, 'style="solid"')
                safe_source = source.replace("-", "_")
                safe_target = target.replace("-", "_")
                label = edge_type.value if edge_type else "requires"
                lines.append(
                    f'  {safe_source} -> {safe_target} [{style} label="{label}"];'
                )

        lines.append("}")
        return "\n".join(lines)

    @staticmethod
    def to_mermaid(graph: DependencyGraph, title: str = "Dependencies") -> str:
        """
        Export dependency graph to Mermaid diagram format.

        Args:
            graph: DependencyGraph to export
            title: Graph title (used as comment)

        Returns:
            Mermaid format string
        """
        lines = [
            f"%%{{ title: {title} }}%%",
            "graph LR",
        ]

        # Add edges
        edges_added = False
        for source in sorted(graph.nodes):
            for target in sorted(graph.get_successors(source)):
                edge_type = graph.get_edge_type(source, target)
                arrow = _MERMAID_EDGE_STYLES.get(edge_type, "-->")
                label = edge_type.value if edge_type else "requires"
                lines.append(f"  {source}{arrow}|{label}|{target}")
                edges_added = True

        # Add isolated nodes (no edges)
        if not edges_added:
            for node in sorted(graph.nodes):
                lines.append(f"  {node}")
        else:
            # Add any isolated nodes that have no edges
            connected = set()
            for source in graph.nodes:
                if graph.get_successors(source) or graph.get_predecessors(source):
                    connected.add(source)
            for node in sorted(graph.nodes - connected):
                lines.append(f"  {node}")

        return "\n".join(lines)
