"""Tests for the Semantic Scholar API client."""

import pytest
import respx
from httpx import Response

from huntpdf.scholar import ScholarResult, lookup_doi, _extract_pmcid


_SAMPLE_DOI = "10.1038/nature12373"
_S2_URL = f"https://api.semanticscholar.org/graph/v1/paper/DOI:{_SAMPLE_DOI}"


class TestLookupDoi:
    @respx.mock
    def test_returns_all_fields(self):
        respx.get(_S2_URL).mock(
            return_value=Response(
                200,
                json={
                    "openAccessPdf": {
                        "url": "https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4221854",
                        "status": "GREEN",
                    },
                    "externalIds": {
                        "ArXiv": "1304.1068",
                        "DOI": "10.1038/nature12373",
                        "PubMed": "23903748",
                    },
                },
            )
        )
        result = lookup_doi(_SAMPLE_DOI)
        assert result is not None
        assert result.open_access_url == "https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4221854"
        assert result.arxiv_id == "1304.1068"
        assert result.pmcid == "PMC4221854"
        assert result.has_alternatives

    @respx.mock
    def test_doi_not_found(self):
        respx.get(_S2_URL).mock(return_value=Response(404))
        assert lookup_doi(_SAMPLE_DOI) is None

    @respx.mock
    def test_no_open_access(self):
        respx.get(_S2_URL).mock(
            return_value=Response(
                200,
                json={
                    "openAccessPdf": None,
                    "externalIds": {"DOI": "10.1038/nature12373"},
                },
            )
        )
        result = lookup_doi(_SAMPLE_DOI)
        assert result is not None
        assert result.open_access_url is None
        assert result.arxiv_id is None
        assert result.pmcid is None
        assert not result.has_alternatives

    @respx.mock
    def test_only_arxiv_id(self):
        respx.get(_S2_URL).mock(
            return_value=Response(
                200,
                json={
                    "openAccessPdf": None,
                    "externalIds": {"ArXiv": "2301.07041"},
                },
            )
        )
        result = lookup_doi(_SAMPLE_DOI)
        assert result is not None
        assert result.arxiv_id == "2301.07041"
        assert result.has_alternatives

    @respx.mock
    def test_http_error_returns_none(self):
        respx.get(_S2_URL).mock(return_value=Response(500))
        assert lookup_doi(_SAMPLE_DOI) is None

    @respx.mock
    def test_network_error_returns_none(self):
        import httpx as _httpx
        respx.get(_S2_URL).mock(side_effect=_httpx.ConnectError("connection refused"))
        assert lookup_doi(_SAMPLE_DOI) is None


class TestExtractPmcid:
    def test_pmc_url(self):
        assert _extract_pmcid("https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4221854") == "PMC4221854"

    def test_new_pmc_url(self):
        assert _extract_pmcid("https://pmc.ncbi.nlm.nih.gov/articles/PMC4221854/") == "PMC4221854"

    def test_no_pmcid(self):
        assert _extract_pmcid("https://arxiv.org/pdf/1304.1068") is None

    def test_empty(self):
        assert _extract_pmcid("") is None

    def test_lowercase_pmc(self):
        assert _extract_pmcid("https://example.com/pmc1234567") == "PMC1234567"
