"""Reality Check sub-client — fact attestation, evidence, and lattice graph."""

from __future__ import annotations

from typing import Any, Mapping, Sequence

from sbn._http import HttpTransport

PREFIX = "/api/reality"


class RealityClient:
    """Fact attestation, evidence management, and reality lattice queries.

    Example::

        client = SbnClient(base_url="https://api.smartblocks.network")
        client.authenticate_api_key("sbn_live_abc123")

        # Create a fact (claims auto-extracted if not provided)
        result = client.reality.create_fact(
            "GDP grew 3.2% in Q4 2025 and inflation fell to 2.1%."
        )

        # Ingest evidence (reliability resolved from source registry)
        client.reality.ingest_evidence([{
            "source_uri": "https://bls.gov/report/2025q4",
            "extracted_claims": ["GDP grew 3.2% in Q4 2025"],
        }])

        # Recompute scores
        client.reality.recompute(result["fact_id"])
    """

    def __init__(self, transport: HttpTransport) -> None:
        self._t = transport

    # ── Facts ──────────────────────────────────────────────────────

    def create_fact(
        self,
        text: str,
        *,
        entities: Sequence[str] | None = None,
        claims: Sequence[str] | None = None,
        citations: Sequence[str] | None = None,
        is_public: bool = False,
    ) -> dict[str, Any]:
        """Create a new fact in the reality lattice.

        If ``claims`` is empty the server will auto-extract atomic claims
        from ``text`` using its built-in claim extractor.
        """
        body: dict[str, Any] = {"text": text, "is_public": is_public}
        if entities:
            body["entities"] = list(entities)
        if claims:
            body["claims"] = list(claims)
        if citations:
            body["citations"] = list(citations)
        return self._t.post(f"{PREFIX}/facts", json=body).json()

    def get_fact(self, fact_id: str) -> dict[str, Any]:
        """Fetch a single fact with scores."""
        return self._t.get(f"{PREFIX}/facts/{fact_id}").json()

    def list_facts(
        self,
        *,
        entity: str | None = None,
        state: str | None = None,
        include_public: bool = False,
        limit: int = 100,
        offset: int = 0,
    ) -> dict[str, Any]:
        """List facts with optional filters."""
        params: dict[str, Any] = {"limit": limit, "offset": offset}
        if entity:
            params["entity"] = entity
        if state:
            params["state"] = state
        if include_public:
            params["include_public"] = "true"
        return self._t.get(f"{PREFIX}/facts", params=params).json()

    def search_facts(
        self,
        *,
        entity: str | None = None,
        state: str | None = None,
    ) -> list[dict[str, Any]]:
        """Search facts by entity and/or state. Returns items list."""
        params: dict[str, Any] = {}
        if entity:
            params["entity"] = entity
        if state:
            params["state"] = state
        data = self._t.get(f"{PREFIX}/facts", params=params).json()
        return data.get("items", [])

    # ── Evidence ────────────────────────────────────────────────────

    def ingest_evidence(
        self,
        items: Sequence[Mapping[str, Any]],
    ) -> dict[str, Any]:
        """Ingest a batch of evidence items into the project lattice.

        Each item should contain at minimum ``source_uri`` and
        ``extracted_claims``.  If ``reliability`` is omitted the server
        resolves it from its source reliability registry.
        """
        body = {"items": [dict(i) for i in items]}
        return self._t.post(f"{PREFIX}/evidence", json=body).json()

    # ── Scoring ─────────────────────────────────────────────────────

    def recompute(self, fact_id: str) -> dict[str, Any]:
        """Recompute trust/density/compression scores for a fact.

        Returns the new scores, state, and a signed receipt hash.
        """
        return self._t.post(f"{PREFIX}/facts/{fact_id}/recompute", json={}).json()

    # ── Graph ───────────────────────────────────────────────────────

    def get_lattice(self) -> dict[str, Any]:
        """Return the full lattice graph (nodes + edges) for visualization."""
        return self._t.get(f"{PREFIX}/lattice").json()

    # ── Health ──────────────────────────────────────────────────────

    def health(self) -> dict[str, Any]:
        """Check Reality Check service health."""
        return self._t.get(f"{PREFIX}/health").json()
