import httpx
import respx

from mcsci_hub.clients.openalex import OpenAlexClient
from tests.conftest import SAMPLE_OPENALEX_SEARCH, SAMPLE_OPENALEX_WORK


@respx.mock
async def test_search(openalex_client: OpenAlexClient):
    respx.get("https://api.openalex.org/works").mock(
        return_value=httpx.Response(200, json=SAMPLE_OPENALEX_SEARCH)
    )
    results = await openalex_client.search("attention transformers")
    assert len(results) == 1
    assert results[0]["title"] == "Attention Is All You Need"


@respx.mock
async def test_get_work(openalex_client: OpenAlexClient):
    respx.get("https://api.openalex.org/works/doi:10.1038/nature12373").mock(
        return_value=httpx.Response(200, json=SAMPLE_OPENALEX_WORK)
    )
    result = await openalex_client.get_work("10.1038/nature12373")
    assert result is not None
    assert result["title"] == "Attention Is All You Need"


@respx.mock
async def test_get_work_not_found(openalex_client: OpenAlexClient):
    respx.get("https://api.openalex.org/works/doi:10.0000/nope").mock(
        return_value=httpx.Response(404)
    )
    result = await openalex_client.get_work("10.0000/nope")
    assert result is None


def test_decode_abstract():
    idx = {"The": [0], "cat": [1], "sat": [2], "on": [3], "the": [4], "mat": [5]}
    text = OpenAlexClient.decode_abstract(idx)
    assert text == "The cat sat on the mat"


def test_decode_abstract_empty():
    assert OpenAlexClient.decode_abstract(None) == ""
    assert OpenAlexClient.decode_abstract({}) == ""


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


def test_parse_doi():
    doi = OpenAlexClient.parse_doi(SAMPLE_OPENALEX_WORK)
    assert doi == "10.1038/nature12373"


def test_parse_year():
    assert OpenAlexClient.parse_year(SAMPLE_OPENALEX_WORK) == 2017


def test_parse_journal():
    assert OpenAlexClient.parse_journal(SAMPLE_OPENALEX_WORK) == "Nature"


def test_is_oa():
    assert OpenAlexClient.is_oa(SAMPLE_OPENALEX_WORK) is True


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


@respx.mock
async def test_search_with_filters(openalex_client: OpenAlexClient):
    respx.get("https://api.openalex.org/works").mock(
        return_value=httpx.Response(200, json=SAMPLE_OPENALEX_SEARCH)
    )
    results = await openalex_client.search(
        "test", year_from=2015, year_to=2020, open_access_only=True,
    )
    assert len(results) == 1
