"""ND0801: Node uses default name."""

import re
from pathlib import Path
from typing import Any

from valn8n_lib.rules._catalog import NODE_CATALOG
from valn8n_lib.rules.registry import SourceMap, register
from valn8n_lib.source_map import lookup_line
from valn8n_lib.types import Diagnostic, Location, RuleCode, Severity, SuggestionLevel

_RULE_CODE = RuleCode("ND0801", Severity.HINT)


@register(
    "ND0801",
    Severity.HINT,
    description="Node uses default name",
    strict=False,
)
def check_default_node_name(
    workflow: dict[str, Any],
    path: Path,
    source_map: SourceMap = None,
    suggestions: SuggestionLevel = SuggestionLevel.FULL,
) -> list[Diagnostic]:
    """Flag nodes whose name matches the default display name (optionally with a number suffix)."""
    diagnostics: list[Diagnostic] = []
    fname = str(path)

    for i, node in enumerate(workflow.get("nodes", [])):
        if node.get("disabled"):
            continue

        node_type = node.get("type", "")

        # Skip sticky notes — they always have a default name
        if node_type == "n8n-nodes-base.stickyNote":
            continue

        catalog_entry = NODE_CATALOG.get(node_type)
        if catalog_entry is None:
            continue

        display_name = catalog_entry.get("display_name", "")
        if not display_name:
            continue

        node_name = node.get("name", "")
        if re.fullmatch(re.escape(display_name) + r"\d*", node_name):
            pointer = f"/nodes/{i}/name"
            line = lookup_line(source_map, pointer)
            diagnostics.append(
                Diagnostic(
                    file=fname,
                    location=Location(node_name, "name"),
                    code=_RULE_CODE,
                    message=(
                        f'Node "{node_name}" uses default name;'
                        " consider giving it a descriptive name"
                    ),
                    line=line,
                ),
            )

    return diagnostics
