from blends.ctx import ctx
from blends.models import (
    NId,
)
from blends.stack.edges import (
    Edge,
    add_edge,
)
from blends.stack.node_helpers import (
    pop_scoped_symbol_node_attributes,
)
from blends.syntax.builders.import_reference_chain import (
    build_import_reference_chain_to_root,
    extract_module_stem,
)
from blends.syntax.builders.utils import (
    get_next_binding_precedence,
)
from blends.syntax.models import (
    SyntaxGraphArgs,
)


def _bound_import_symbol(*, expression: str, alias: str | None) -> str:
    if isinstance(alias, str) and alias:
        return alias
    parts = expression.split(".")
    return parts[-1] if parts else expression


def build_import_module_node(
    args: SyntaxGraphArgs,
    expression: str,
    alias: str | None = None,
    module_path: str | None = None,
) -> NId:
    args.syntax_graph.add_node(
        args.n_id,
        expression=expression,
        label_type="ModuleImport",
    )

    if alias:
        args.syntax_graph.update_node_attribute(args.n_id, "label_alias", alias)

    if ctx.has_feature_flag("StackGraph"):
        bound = _bound_import_symbol(expression=expression, alias=alias)
        if bound:
            precedence = get_next_binding_precedence(args)
            module_stem = (
                extract_module_stem(module_path)
                if module_path is not None
                else extract_module_stem(expression)
            )
            args.syntax_graph.update_node(
                args.n_id,
                pop_scoped_symbol_node_attributes(
                    symbol=bound,
                    precedence=precedence,
                    is_import_binding=True,
                    import_module_stem=module_stem,
                ),
            )
            scope_stack = args.metadata.setdefault("scope_stack", [])
            if scope_stack and (parent_scope := scope_stack[-1]):
                add_edge(
                    args.syntax_graph,
                    Edge(source=parent_scope, sink=args.n_id, precedence=precedence),
                )
            build_import_reference_chain_to_root(args, module_stem, args.n_id)

    return args.n_id
