"""OpenAlex — REST API with inverted-index abstract reconstruction."""

from __future__ import annotations

from platoon.models import Item
from platoon.fetcher import Fetcher


def _reconstruct_abstract(inverted_index: dict) -> str:
    """Rebuild plain text from OpenAlex inverted-index abstract."""
    if not inverted_index:
        return ""
    word_positions = []
    for word, positions in inverted_index.items():
        for pos in positions:
            word_positions.append((pos, word))
    word_positions.sort()
    return " ".join(w for _, w in word_positions)


def fetch_openalex(cfg: dict, fetcher: Fetcher) -> list[Item]:
    base = cfg.get("endpoint", "https://api.openalex.org/works")
    queries = cfg.get("queries", ["machine learning"])
    max_items = cfg.get("max_items", 10)
    email = cfg.get("email", "")
    items = []

    for query in queries:
        print(f"Fetching OpenAlex [{query[:40]}]...")
        params = {
            "search": query,
            "per_page": max_items,
            "sort": "publication_date:desc",
        }
        if email:
            params["mailto"] = email
        resp = fetcher.get(base, params=params)
        if not resp:
            continue
        data = resp.json()
        for work in data.get("results", []):
            abstract = _reconstruct_abstract(
                work.get("abstract_inverted_index", {})
            )
            url = work.get("doi") or work.get("id", "")
            if url and url.startswith("https://doi.org/"):
                pass  # already a URL
            elif url and not url.startswith("http"):
                url = f"https://openalex.org/works/{url}"
            items.append(Item(
                title=work.get("title", "") or work.get("display_name", ""),
                url=url,
                source="OpenAlex",
                summary=abstract[:400],
                engagement={
                    "citations": work.get("cited_by_count", 0),
                },
            ))

    print(f"  -> {len(items)} total items")
    return items
