"""Tests para extract_graph_from_text pipeline.

Usa stubs para GLiNER2 para validar el flujo completo sin descargar modelos.
"""

from __future__ import annotations

import os
import sys

import pytest

sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", "..", ".."))

from python.functions.pipelines.extract_graph_from_text import extract_graph_from_text


class _Schema:
    def entities(self, labels):
        return self

    def relations(self, labels):
        return self


class _StubModel:
    """Stub que retorna un grafo conocido para cualquier texto."""

    def create_schema(self):
        return _Schema()

    def extract(self, text, schema=None, threshold=0.3, include_confidence=False):
        return {
            "entities": {
                "person": ["Carlos Torres"],
                "organization": ["BBVA"],
                "location": ["Bilbao"],
            },
            "relation_extraction": {
                "president_of": [("Carlos Torres", "BBVA")],
                "headquartered_in": [("BBVA", "Bilbao")],
            },
        }


ENTITY_LABELS = ["person", "organization", "location"]
RELATION_LABELS = ["president_of", "headquartered_in", "works_at"]
ALLOWED = {
    "president_of": (["person"], ["organization"]),
    "headquartered_in": (["organization"], ["location"]),
}


def test_texto_corto_produce_nodos_y_aristas_esperados():
    """texto corto produce nodos y aristas esperados con stub model"""
    text = "Carlos Torres es presidente de BBVA con sede en Bilbao."
    result = extract_graph_from_text(
        text=text,
        entity_labels=ENTITY_LABELS,
        relation_labels=RELATION_LABELS,
        allowed=ALLOWED,
        model=_StubModel(),
        threshold=0.3,
    )

    node_ids = {n["id"] for n in result["nodes"]}
    assert "Carlos Torres" in node_ids
    assert "BBVA" in node_ids
    assert "Bilbao" in node_ids

    edge_kinds = {e["kind"] for e in result["edges"]}
    assert "president_of" in edge_kinds
    assert "headquartered_in" in edge_kinds


def test_stats_tiene_todos_los_campos_requeridos():
    """stats tiene todos los campos requeridos"""
    text = "Texto de prueba para el pipeline."
    result = extract_graph_from_text(
        text=text,
        entity_labels=ENTITY_LABELS,
        relation_labels=RELATION_LABELS,
        allowed=ALLOWED,
        model=_StubModel(),
    )
    stats = result["stats"]
    assert "n_chunks" in stats
    assert "n_nodes" in stats
    assert "n_edges" in stats
    assert "n_dropped_typed" in stats
    assert "elapsed_s" in stats
    assert stats["n_chunks"] >= 1
    assert stats["n_nodes"] >= 0
