"""Tests para extract_triples_spacy_es.

Requiere spaCy y es_core_news_md instalados. Si no estan, los tests se omiten.
"""

from __future__ import annotations

import os
import sys

import pytest

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

from python.functions.datascience.extract_triples_spacy_es import extract_triples_spacy_es

spacy = pytest.importorskip("spacy", reason="spacy not installed — skip")


def _load_nlp():
    try:
        return spacy.load("es_core_news_md")
    except OSError:
        return None


_NLP = _load_nlp()
pytestmark = pytest.mark.skipif(
    _NLP is None,
    reason="es_core_news_md not installed — run: python -m spacy download es_core_news_md",
)


def test_oracion_simple_produce_tripleta_con_sujeto_verbo_objeto():
    """oracion simple produce tripleta con sujeto verbo objeto"""
    result = extract_triples_spacy_es("Enmanuel quiere a Ashlly.", _NLP)
    assert len(result["triples"]) >= 1
    # Al menos una tripleta con sujeto que contenga Enmanuel
    subjs = [t["subject"] for t in result["triples"]]
    assert any("Enmanuel" in s or "enmanuel" in s.lower() for s in subjs)


def test_carlos_torres_preside_bbva():
    """carlos torres preside bbva produce tripleta president"""
    result = extract_triples_spacy_es("Carlos Torres preside BBVA.", _NLP)
    triples = result["triples"]
    assert len(triples) >= 1
    rels = [t["relation"] for t in triples]
    assert any("presidir" in r or "presidir" in r.lower() for r in rels)


def test_amancio_ortega_fundo_inditex_en_1985():
    """amancio ortega fundo inditex en 1985 produce tripletas con fundar_en"""
    result = extract_triples_spacy_es(
        "Amancio Ortega fundo Inditex en 1985.", _NLP
    )
    triples = result["triples"]
    assert len(triples) >= 1
    # El verbo y sus objetos deben producir al menos 2 tripletas (Inditex + 1985 como oblicuo)
    subjs = {t["subject"] for t in triples}
    assert any("Amancio" in s or "Ortega" in s for s in subjs)
    # Debe haber al menos la tripleta directa con Inditex
    objects = {t["object"] for t in triples}
    assert any("Inditex" in o or "1985" in o for o in objects)


def test_texto_sin_verbos_produce_tripletas_vacias():
    """texto sin verbos produce tripletas vacias"""
    result = extract_triples_spacy_es("BBVA Santander Inditex.", _NLP)
    assert result["triples"] == []


def test_entities_ner_detecta_categorias():
    """entities NER detecta PER ORG LOC"""
    result = extract_triples_spacy_es(
        "Carlos Torres es presidente de BBVA en Bilbao.", _NLP
    )
    ents = result["entities"]
    labels = {e["label"] for e in ents}
    # Debe detectar al menos uno de PER, ORG o LOC
    assert labels & {"PER", "ORG", "LOC"}
