"""
Simple attack graph data structure for dashboard visualization.

Provides a lightweight graph of attack nodes and edges for vis.js rendering.
"""

import uuid
from typing import Dict


def init_simple_graph() -> dict:
    """Initialize a simple attack graph data structure."""
    return {
        "nodes": [
            {
                "id": "start",
                "label": "START",
                "type": "initial",
                "visit_count": 0,
                "success_rate": 0,
            }
        ],
        "edges": [],
        "current_node": "start",
        "node_counter": 0,
    }


def add_attack_to_simple_graph(
    graph: dict,
    attack_type: str,
    pattern: str,
    agent: str,
    outcome: str,  # "success", "partial", "blocked", "probe"
    has_findings: bool,
) -> dict:
    """Add an attack result to the simple graph.

    Args:
        graph: The simple graph dict
        attack_type: Type of attack
        pattern: Attack pattern name
        agent: Agent name
        outcome: Result outcome string
        has_findings: Whether findings were detected

    Returns:
        Updated graph dict
    """
    # Increment counter for unique node naming
    graph["node_counter"] += 1
    node_num = graph["node_counter"]

    # Create new node
    new_node_id = f"n{node_num}"

    # Determine node type based on outcome
    if outcome == "success" or has_findings:
        node_type = "jailbreak" if has_findings else "partial"
    elif outcome == "blocked":
        node_type = "dead_end"
    else:
        node_type = "probe"

    new_node = {
        "id": new_node_id,
        "label": f"N{node_num}",
        "type": node_type,
        "visit_count": 1,
        "success_rate": 1.0 if has_findings else 0.0,
    }

    # Create edge from current node to new node
    edge_id = f"e{uuid.uuid4().hex[:6]}"
    new_edge = {
        "id": edge_id,
        "from": graph["current_node"],
        "to": new_node_id,
        "attack_type": attack_type,
        "agent": agent,
        "pattern": pattern[:30] if pattern else "unknown",  # Truncate for display
        "outcome": outcome,
    }

    # Update graph
    graph["nodes"].append(new_node)
    graph["edges"].append(new_edge)
    graph["current_node"] = new_node_id

    return graph


def get_graph_summary(graph: Dict) -> Dict:
    """Get a summary of the attack graph for logging."""
    if not graph:
        return {"nodes": 0, "edges": 0}

    nodes = graph.get("nodes", [])
    edges = graph.get("edges", [])

    node_types = {}
    for node in nodes:
        ntype = node.get("type", "unknown")
        node_types[ntype] = node_types.get(ntype, 0) + 1

    return {
        "total_nodes": len(nodes),
        "total_edges": len(edges),
        "node_types": node_types,
        "current_node": graph.get("current_node", "unknown"),
    }
