from __future__ import annotations

from .artifact_registry import PackValidationResult
from .concept_graph import ConceptGraph
from .learning_graph import build_merged_learning_graph, namespaced_concept
from .semantic_similarity import concept_similarity


def build_concept_graph(results: list[PackValidationResult], default_dimension_thresholds: dict[str, float]) -> ConceptGraph:
    merged = build_merged_learning_graph(results, default_dimension_thresholds)
    graph = ConceptGraph()

    for concept_key, data in merged.concept_data.items():
        graph.add_concept(concept_key, data)

    for concept_key, data in merged.concept_data.items():
        for prereq in data["prerequisites"]:
            if prereq in merged.concept_data:
                graph.add_prerequisite(prereq, concept_key)

    for result in results:
        if result.manifest is None or not result.is_valid:
            continue
        pack_name = result.manifest.name
        for link in result.manifest.cross_pack_links:
            source = link.source_concept if "::" in link.source_concept else namespaced_concept(pack_name, link.source_concept)
            target = link.target_concept
            if source in graph.graph.nodes and target in graph.graph.nodes:
                graph.add_cross_link(source, target, link.relation)

    return graph


def suggest_semantic_links(graph: ConceptGraph, minimum_similarity: float = 0.35) -> list[tuple[str, str, float]]:
    concepts = list(graph.graph.nodes(data=True))
    found = []
    for i in range(len(concepts)):
        key_a, data_a = concepts[i]
        for j in range(i + 1, len(concepts)):
            key_b, data_b = concepts[j]
            if key_a.split("::")[0] == key_b.split("::")[0]:
                continue
            sim = concept_similarity(data_a, data_b)
            if sim >= minimum_similarity:
                found.append((key_a, key_b, sim))
    return sorted(found, key=lambda x: x[2], reverse=True)
