import httpx
import respx

from mcsci_hub.clients.crossref import CrossRefClient
from tests.conftest import SAMPLE_CROSSREF_SEARCH, SAMPLE_CROSSREF_WORK


@respx.mock
async def test_search(crossref_client: CrossRefClient):
    respx.get("https://api.crossref.org/works").mock(
        return_value=httpx.Response(200, json=SAMPLE_CROSSREF_SEARCH)
    )
    results = await crossref_client.search("attention transformers")
    assert len(results) == 1
    assert results[0]["DOI"] == "10.1038/nature12373"


@respx.mock
async def test_get_work(crossref_client: CrossRefClient):
    respx.get("https://api.crossref.org/works/10.1038/nature12373").mock(
        return_value=httpx.Response(200, json={"message": SAMPLE_CROSSREF_WORK})
    )
    result = await crossref_client.get_work("10.1038/nature12373")
    assert result is not None
    assert result["DOI"] == "10.1038/nature12373"


@respx.mock
async def test_get_work_not_found(crossref_client: CrossRefClient):
    respx.get("https://api.crossref.org/works/10.0000/nonexistent").mock(
        return_value=httpx.Response(404)
    )
    result = await crossref_client.get_work("10.0000/nonexistent")
    assert result is None


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


def test_parse_year():
    year = CrossRefClient.parse_year(SAMPLE_CROSSREF_WORK)
    assert year == 2017


def test_parse_title():
    title = CrossRefClient.parse_title(SAMPLE_CROSSREF_WORK)
    assert title == "Attention Is All You Need"


def test_parse_journal():
    journal = CrossRefClient.parse_journal(SAMPLE_CROSSREF_WORK)
    assert journal == "Nature"


@respx.mock
async def test_search_with_year_filter(crossref_client: CrossRefClient):
    respx.get("https://api.crossref.org/works").mock(
        return_value=httpx.Response(200, json=SAMPLE_CROSSREF_SEARCH)
    )
    results = await crossref_client.search("attention", year_from=2017, year_to=2020)
    assert len(results) == 1


@respx.mock
async def test_search_network_error(crossref_client: CrossRefClient):
    respx.get("https://api.crossref.org/works").mock(side_effect=httpx.ConnectError("fail"))
    results = await crossref_client.search("test")
    assert results == []
