"""
Reputation resource clients (sync and async) for querying scores,
domain-specific reputation, history, batch lookups, and attestations.
"""

from __future__ import annotations

from typing import Any
from urllib.parse import quote

from ..http import HttpClient, AsyncHttpClient
from ..models import (
    ReputationScore,
    DomainReputation,
    ReputationHistory,
    ReputationAttestation,
)


class ReputationClient:
    """Synchronous client for reputation endpoints."""

    def __init__(self, http: HttpClient) -> None:
        self._http = http

    def get(self, agent_id: str) -> ReputationScore:
        """Get the overall reputation score for an agent across all domains."""
        data = self._http.get(f"/v1/reputation/{quote(agent_id, safe='')}")
        return ReputationScore.model_validate(data)

    def get_domain(self, agent_id: str, domain: str) -> DomainReputation:
        """Get the reputation score for an agent in a specific domain."""
        data = self._http.get(
            f"/v1/reputation/{quote(agent_id, safe='')}/domains/{quote(domain, safe='')}"
        )
        return DomainReputation.model_validate(data)

    def get_history(
        self,
        agent_id: str,
        from_time: str | None = None,
        to_time: str | None = None,
        limit: int | None = None,
    ) -> ReputationHistory:
        """Get the historical reputation changes for an agent."""
        params: dict[str, Any] = {
            "from": from_time,
            "to": to_time,
            "limit": limit,
        }
        data = self._http.get(
            f"/v1/reputation/{quote(agent_id, safe='')}/history",
            params,
        )
        return ReputationHistory.model_validate(data)

    def batch(self, agent_ids: list[str]) -> dict[str, ReputationScore]:
        """Fetch reputation scores for multiple agents in a single request."""
        data = self._http.post("/v1/reputation/batch", {"agentIds": agent_ids})
        return {
            agent_id: ReputationScore.model_validate(score_data)
            for agent_id, score_data in data.get("scores", {}).items()
        }

    def get_attestation(self, agent_id: str) -> ReputationAttestation:
        """Get a cryptographic attestation of an agent's reputation score."""
        data = self._http.get(
            f"/v1/reputation/{quote(agent_id, safe='')}/attestation"
        )
        return ReputationAttestation.model_validate(data)


class AsyncReputationClient:
    """Asynchronous client for reputation endpoints."""

    def __init__(self, http: AsyncHttpClient) -> None:
        self._http = http

    async def get(self, agent_id: str) -> ReputationScore:
        """Get the overall reputation score for an agent across all domains."""
        data = await self._http.get(f"/v1/reputation/{quote(agent_id, safe='')}")
        return ReputationScore.model_validate(data)

    async def get_domain(self, agent_id: str, domain: str) -> DomainReputation:
        """Get the reputation score for an agent in a specific domain."""
        data = await self._http.get(
            f"/v1/reputation/{quote(agent_id, safe='')}/domains/{quote(domain, safe='')}"
        )
        return DomainReputation.model_validate(data)

    async def get_history(
        self,
        agent_id: str,
        from_time: str | None = None,
        to_time: str | None = None,
        limit: int | None = None,
    ) -> ReputationHistory:
        """Get the historical reputation changes for an agent."""
        params: dict[str, Any] = {
            "from": from_time,
            "to": to_time,
            "limit": limit,
        }
        data = await self._http.get(
            f"/v1/reputation/{quote(agent_id, safe='')}/history",
            params,
        )
        return ReputationHistory.model_validate(data)

    async def batch(self, agent_ids: list[str]) -> dict[str, ReputationScore]:
        """Fetch reputation scores for multiple agents in a single request."""
        data = await self._http.post("/v1/reputation/batch", {"agentIds": agent_ids})
        return {
            agent_id: ReputationScore.model_validate(score_data)
            for agent_id, score_data in data.get("scores", {}).items()
        }

    async def get_attestation(self, agent_id: str) -> ReputationAttestation:
        """Get a cryptographic attestation of an agent's reputation score."""
        data = await self._http.get(
            f"/v1/reputation/{quote(agent_id, safe='')}/attestation"
        )
        return ReputationAttestation.model_validate(data)
