import httpx
import respx

from mcsci_hub.clients.semantic_scholar import SemanticScholarClient
from tests.conftest import SAMPLE_S2_CITATIONS, SAMPLE_S2_PAPER, SAMPLE_S2_REFERENCES

S2_BASE = "https://api.semanticscholar.org/graph/v1"


@respx.mock
async def test_get_paper(s2_client: SemanticScholarClient):
    respx.get(f"{S2_BASE}/paper/DOI:10.1038/nature12373").mock(
        return_value=httpx.Response(200, json=SAMPLE_S2_PAPER)
    )
    result = await s2_client.get_paper("10.1038/nature12373")
    assert result is not None
    assert result["title"] == "Attention Is All You Need"
    assert result["citationCount"] == 52000


@respx.mock
async def test_get_paper_not_found(s2_client: SemanticScholarClient):
    respx.get(f"{S2_BASE}/paper/DOI:10.0000/nope").mock(
        return_value=httpx.Response(404)
    )
    result = await s2_client.get_paper("10.0000/nope")
    assert result is None


@respx.mock
async def test_get_citations(s2_client: SemanticScholarClient):
    respx.get(f"{S2_BASE}/paper/DOI:10.1038/nature12373/citations").mock(
        return_value=httpx.Response(200, json=SAMPLE_S2_CITATIONS)
    )
    results = await s2_client.get_citations("10.1038/nature12373")
    assert len(results) == 1
    citing = results[0]["citingPaper"]
    assert "BERT" in citing["title"]


@respx.mock
async def test_get_references(s2_client: SemanticScholarClient):
    respx.get(f"{S2_BASE}/paper/DOI:10.1038/nature12373/references").mock(
        return_value=httpx.Response(200, json=SAMPLE_S2_REFERENCES)
    )
    results = await s2_client.get_references("10.1038/nature12373")
    assert len(results) == 1
    cited = results[0]["citedPaper"]
    assert "Neural Machine Translation" in cited["title"]


def test_parse_authors():
    authors = SemanticScholarClient.parse_authors(SAMPLE_S2_PAPER)
    assert authors == ["Ashish Vaswani", "Noam Shazeer"]


def test_parse_doi():
    doi = SemanticScholarClient.parse_doi(SAMPLE_S2_PAPER)
    assert doi == "10.1038/nature12373"


def test_get_bibtex():
    bibtex = SemanticScholarClient.get_bibtex(SAMPLE_S2_PAPER)
    assert bibtex.startswith("@article")


def test_get_oa_url():
    url = SemanticScholarClient.get_oa_url(SAMPLE_S2_PAPER)
    assert url == "https://arxiv.org/pdf/1706.03762"


@respx.mock
async def test_get_citations_network_error(s2_client: SemanticScholarClient):
    respx.get(f"{S2_BASE}/paper/DOI:10.1038/nature12373/citations").mock(
        side_effect=httpx.ConnectError("fail")
    )
    results = await s2_client.get_citations("10.1038/nature12373")
    assert results == []
