"""Semantic Scholar API client for finding open-access PDFs."""

from dataclasses import dataclass

import httpx

_S2_API_BASE = "https://api.semanticscholar.org/graph/v1"
_TIMEOUT = 30.0
_FIELDS = "openAccessPdf,externalIds"


@dataclass
class ScholarResult:
    """Holds open-access info from Semantic Scholar."""

    open_access_url: str | None
    arxiv_id: str | None
    pmcid: str | None

    @property
    def has_alternatives(self) -> bool:
        return bool(self.open_access_url or self.arxiv_id or self.pmcid)


def lookup_doi(doi: str) -> ScholarResult | None:
    """Query Semantic Scholar for open-access PDF sources for a DOI.

    Args:
        doi: A DOI string (e.g. "10.1038/nature12373").

    Returns:
        ScholarResult with available open-access info, or None if not found.
    """
    url = f"{_S2_API_BASE}/paper/DOI:{doi}?fields={_FIELDS}"
    try:
        response = httpx.get(url, timeout=_TIMEOUT)
        if response.status_code == 404:
            return None
        response.raise_for_status()
    except httpx.HTTPError:
        return None

    data = response.json()
    ext_ids = data.get("externalIds") or {}
    oa_pdf = data.get("openAccessPdf") or {}

    # Extract PMCID from the open access URL if it's a PMC link
    pmcid = _extract_pmcid(oa_pdf.get("url", ""))

    return ScholarResult(
        open_access_url=oa_pdf.get("url"),
        arxiv_id=ext_ids.get("ArXiv"),
        pmcid=pmcid,
    )


def _extract_pmcid(url: str) -> str | None:
    """Extract a PMC ID from a URL like https://...pmc/.../PMC1234567."""
    if not url:
        return None
    # Match PMC followed by digits anywhere in the URL path
    import re
    match = re.search(r"(PMC\d+)", url, re.IGNORECASE)
    return match.group(1).upper() if match else None
