from typing import TypedDict, cast

from blends.models import (
    NId,
)
from blends.syntax.models import (
    SyntaxGraphArgs,
)


class DirectChildren(TypedDict, total=False):
    expression_id: NId
    arguments_id: NId
    object_id: NId
    block_id: NId


def _process_invocation_children(
    args: SyntaxGraphArgs,
    children: DirectChildren,
) -> None:
    for name_node, child_id in cast("dict[str, NId]", children).items():
        args.syntax_graph.update_node_attribute(args.n_id, name_node, child_id)
        args.syntax_graph.add_edge(
            args.n_id,
            args.generic(args.fork_n_id(child_id)),
            label_ast="AST",
        )


def build_method_invocation_node(
    args: SyntaxGraphArgs,
    expr: str,
    direct_children: DirectChildren,
    object_name: str | None = None,
) -> NId:
    args.syntax_graph.add_node(
        args.n_id,
        expression=expr,
        label_type="MethodInvocation",
    )
    if object_name:
        args.syntax_graph.update_node_attribute(args.n_id, "object", object_name)
    _process_invocation_children(args, direct_children)
    return args.n_id
