from __future__ import annotations

from typing import Any

import httpx

from ._admin_client import AdminBaseClient
from ._constants import DEFAULT_TIMEOUT
from ._response import RungateResponse

# ─── Sync Admin Client ────────────────────────────────────


class Admin(AdminBaseClient):
    """Synchronous admin client for Rungate management API.

    Usage:
        admin = Admin(token="rg_adm_...", base_url="http://localhost:8080")
        agents = admin.agents.list()
        admin.approvals.approve("request-id")

    Or as a context manager:
        with Admin(token="rg_adm_...") as admin:
            admin.alert_rules.create(name="high-cost", ...)
    """

    def __init__(
        self,
        token: str | None = None,
        base_url: str | None = None,
        timeout: float = DEFAULT_TIMEOUT,
    ) -> None:
        super().__init__(token=token, base_url=base_url, timeout=timeout)
        self._http_client = httpx.Client(timeout=self.timeout)
        self.provider_keys = ProviderKeysResource(self)
        self.policies = PoliciesResource(self)
        self.agents = AgentsResource(self)
        self.runs = RunsResource(self)
        self.webhooks = WebhooksResource(self)
        self.tokens = TokensResource(self)
        self.approvals = ApprovalsResource(self)
        self.alert_rules = AlertRulesResource(self)
        self.analytics = AnalyticsResource(self)
        self.providers = ProvidersResource(self)

    def _request(
        self,
        method: str,
        path: str,
        *,
        json: dict[str, Any] | None = None,
        params: dict[str, Any] | None = None,
    ) -> RungateResponse:
        url = self._build_url(path)
        filtered_params = {k: v for k, v in (params or {}).items() if v is not None} or None
        http_response = self._http_client.request(
            method,
            url,
            json=json,
            headers=self._build_headers(),
            params=filtered_params,
        )
        response = RungateResponse(http_response)
        return self._handle_response(response)

    def close(self) -> None:
        self._http_client.close()

    def __enter__(self) -> Admin:
        return self

    def __exit__(self, *args: Any) -> None:
        self.close()


# ─── Async Admin Client ──────────────────────────────────


class AsyncAdmin(AdminBaseClient):
    """Asynchronous admin client for Rungate management API."""

    def __init__(
        self,
        token: str | None = None,
        base_url: str | None = None,
        timeout: float = DEFAULT_TIMEOUT,
    ) -> None:
        super().__init__(token=token, base_url=base_url, timeout=timeout)
        self._http_client = httpx.AsyncClient(timeout=self.timeout)
        self.provider_keys = AsyncProviderKeysResource(self)
        self.policies = AsyncPoliciesResource(self)
        self.agents = AsyncAgentsResource(self)
        self.runs = AsyncRunsResource(self)
        self.webhooks = AsyncWebhooksResource(self)
        self.tokens = AsyncTokensResource(self)
        self.approvals = AsyncApprovalsResource(self)
        self.alert_rules = AsyncAlertRulesResource(self)
        self.analytics = AsyncAnalyticsResource(self)
        self.providers = AsyncProvidersResource(self)

    async def _request(
        self,
        method: str,
        path: str,
        *,
        json: dict[str, Any] | None = None,
        params: dict[str, Any] | None = None,
    ) -> RungateResponse:
        url = self._build_url(path)
        filtered_params = {k: v for k, v in (params or {}).items() if v is not None} or None
        http_response = await self._http_client.request(
            method,
            url,
            json=json,
            headers=self._build_headers(),
            params=filtered_params,
        )
        response = RungateResponse(http_response)
        return self._handle_response(response)

    async def close(self) -> None:
        await self._http_client.aclose()

    async def __aenter__(self) -> AsyncAdmin:
        return self

    async def __aexit__(self, *args: Any) -> None:
        await self.close()


# ─── Resource Classes (Sync) ─────────────────────────────


class ProviderKeysResource:
    def __init__(self, client: Admin) -> None:
        self._c = client

    def list(self, *, provider: str | None = None, status: str | None = None) -> dict[str, Any]:
        return self._c._request("GET", "/api/provider-keys", params={"provider": provider, "status": status}).body

    def create(self, *, provider: str, name: str, api_key: str, **kwargs: Any) -> dict[str, Any]:
        return self._c._request(
            "POST", "/api/provider-keys", json={"provider": provider, "name": name, "api_key": api_key, **kwargs}
        ).body

    def get(self, id: str) -> dict[str, Any]:
        return self._c._request("GET", f"/api/provider-keys/{id}").body

    def update(self, id: str, **kwargs: Any) -> dict[str, Any]:
        return self._c._request("PUT", f"/api/provider-keys/{id}", json=kwargs).body

    def delete(self, id: str) -> dict[str, Any]:
        return self._c._request("DELETE", f"/api/provider-keys/{id}").body

    def upsert(self, name: str, **kwargs: Any) -> dict[str, Any]:
        return self._c._request("PUT", f"/api/provider-keys/by-name/{name}", json=kwargs).body


class PoliciesResource:
    def __init__(self, client: Admin) -> None:
        self._c = client

    def list(self, *, name: str | None = None) -> dict[str, Any]:
        return self._c._request("GET", "/api/policies", params={"name": name}).body

    def create(self, *, name: str, **kwargs: Any) -> dict[str, Any]:
        return self._c._request("POST", "/api/policies", json={"name": name, **kwargs}).body

    def get(self, id: str) -> dict[str, Any]:
        return self._c._request("GET", f"/api/policies/{id}").body

    def update(self, id: str, **kwargs: Any) -> dict[str, Any]:
        return self._c._request("PUT", f"/api/policies/{id}", json=kwargs).body

    def delete(self, id: str) -> dict[str, Any]:
        return self._c._request("DELETE", f"/api/policies/{id}").body

    def upsert(self, name: str, **kwargs: Any) -> dict[str, Any]:
        return self._c._request("PUT", f"/api/policies/by-name/{name}", json=kwargs).body

    def versions(self, id: str) -> dict[str, Any]:
        return self._c._request("GET", f"/api/policies/{id}/versions").body

    def version(self, id: str, version_number: int) -> dict[str, Any]:
        return self._c._request("GET", f"/api/policies/{id}/versions/{version_number}").body


class AgentsResource:
    def __init__(self, client: Admin) -> None:
        self._c = client

    def list(self, *, status: str | None = None, policy_id: str | None = None) -> dict[str, Any]:
        return self._c._request("GET", "/api/agents", params={"status": status, "policy_id": policy_id}).body

    def create(self, *, name: str, policy_id: str, **kwargs: Any) -> dict[str, Any]:
        return self._c._request("POST", "/api/agents", json={"name": name, "policy_id": policy_id, **kwargs}).body

    def get(self, id: str) -> dict[str, Any]:
        return self._c._request("GET", f"/api/agents/{id}").body

    def update(self, id: str, **kwargs: Any) -> dict[str, Any]:
        return self._c._request("PUT", f"/api/agents/{id}", json=kwargs).body

    def patch(self, id: str, **kwargs: Any) -> dict[str, Any]:
        """Partial update (PATCH). Same as update() but uses PATCH method."""
        return self._c._request("PATCH", f"/api/agents/{id}", json=kwargs).body

    def rotate_key(self, id: str) -> dict[str, Any]:
        return self._c._request("POST", f"/api/agents/{id}/rotate-key").body

    def upsert(self, name: str, **kwargs: Any) -> dict[str, Any]:
        return self._c._request("PUT", f"/api/agents/by-name/{name}", json=kwargs).body

    def stats(self) -> dict[str, Any]:
        return self._c._request("GET", "/api/agents/stats/all").body


class RunsResource:
    def __init__(self, client: Admin) -> None:
        self._c = client

    def list(
        self,
        *,
        agent_id: str | None = None,
        status: str | None = None,
        since: str | None = None,
        until: str | None = None,
        sort: str | None = None,
        order: str | None = None,
        limit: int | None = None,
        offset: int | None = None,
    ) -> dict[str, Any]:
        return self._c._request(
            "GET",
            "/api/runs",
            params={
                "agent_id": agent_id,
                "status": status,
                "since": since,
                "until": until,
                "sort": sort,
                "order": order,
                "limit": limit,
                "offset": offset,
            },
        ).body

    def get(self, id: str) -> dict[str, Any]:
        return self._c._request("GET", f"/api/runs/{id}").body

    def steps(
        self,
        id: str,
        *,
        sort: str | None = None,
        order: str | None = None,
        limit: int | None = None,
        offset: int | None = None,
    ) -> dict[str, Any]:
        return self._c._request(
            "GET",
            f"/api/runs/{id}/steps",
            params={"sort": sort, "order": order, "limit": limit, "offset": offset},
        ).body

    def ledger(self, id: str) -> dict[str, Any]:
        return self._c._request("GET", f"/api/runs/{id}/ledger").body

    def stop(self, id: str) -> dict[str, Any]:
        return self._c._request("POST", f"/api/runs/{id}/stop").body


class WebhooksResource:
    def __init__(self, client: Admin) -> None:
        self._c = client

    def list(self, *, status: str | None = None, event: str | None = None) -> dict[str, Any]:
        return self._c._request("GET", "/api/webhooks", params={"status": status, "event": event}).body

    def create(self, *, name: str, url: str, events: list[str], **kwargs: Any) -> dict[str, Any]:
        return self._c._request(
            "POST", "/api/webhooks", json={"name": name, "url": url, "events": events, **kwargs}
        ).body

    def get(self, id: str) -> dict[str, Any]:
        return self._c._request("GET", f"/api/webhooks/{id}").body

    def update(self, id: str, **kwargs: Any) -> dict[str, Any]:
        return self._c._request("PUT", f"/api/webhooks/{id}", json=kwargs).body

    def delete(self, id: str) -> dict[str, Any]:
        return self._c._request("DELETE", f"/api/webhooks/{id}").body

    def deliveries(
        self,
        id: str,
        *,
        status: str | None = None,
        event_type: str | None = None,
        limit: int | None = None,
        offset: int | None = None,
    ) -> dict[str, Any]:
        return self._c._request(
            "GET",
            f"/api/webhooks/{id}/deliveries",
            params={"status": status, "event_type": event_type, "limit": limit, "offset": offset},
        ).body

    def test(self, id: str) -> dict[str, Any]:
        return self._c._request("POST", f"/api/webhooks/{id}/test").body

    def enable(self, id: str) -> dict[str, Any]:
        return self._c._request("POST", f"/api/webhooks/{id}/enable").body

    def disable(self, id: str) -> dict[str, Any]:
        return self._c._request("POST", f"/api/webhooks/{id}/disable").body


class TokensResource:
    def __init__(self, client: Admin) -> None:
        self._c = client

    def list(self, *, status: str | None = None) -> dict[str, Any]:
        return self._c._request("GET", "/api/admin-tokens", params={"status": status}).body

    def create(self, *, name: str, scopes: list[str], **kwargs: Any) -> dict[str, Any]:
        return self._c._request("POST", "/api/admin-tokens", json={"name": name, "scopes": scopes, **kwargs}).body

    def get(self, id: str) -> dict[str, Any]:
        return self._c._request("GET", f"/api/admin-tokens/{id}").body

    def revoke(self, id: str) -> dict[str, Any]:
        return self._c._request("POST", f"/api/admin-tokens/{id}/revoke").body


class ApprovalsResource:
    def __init__(self, client: Admin) -> None:
        self._c = client

    def list(
        self,
        *,
        agent_id: str | None = None,
        run_id: str | None = None,
        status: str | None = None,
    ) -> dict[str, Any]:
        return self._c._request(
            "GET",
            "/api/approval-requests",
            params={"agent_id": agent_id, "run_id": run_id, "status": status},
        ).body

    def get(self, id: str) -> dict[str, Any]:
        return self._c._request("GET", f"/api/approval-requests/{id}").body

    def approve(self, id: str) -> dict[str, Any]:
        return self._c._request("POST", f"/api/approval-requests/{id}/approve").body

    def reject(self, id: str, *, reason: str | None = None) -> dict[str, Any]:
        body: dict[str, Any] = {}
        if reason is not None:
            body["reason"] = reason
        return self._c._request("POST", f"/api/approval-requests/{id}/reject", json=body).body


class AlertRulesResource:
    def __init__(self, client: Admin) -> None:
        self._c = client

    def list(
        self,
        *,
        agent_id: str | None = None,
        condition_type: str | None = None,
        status: str | None = None,
    ) -> dict[str, Any]:
        return self._c._request(
            "GET",
            "/api/alert-rules",
            params={"agent_id": agent_id, "condition_type": condition_type, "status": status},
        ).body

    def create(
        self, *, name: str, condition_type: str, condition_config: dict[str, Any], **kwargs: Any
    ) -> dict[str, Any]:
        return self._c._request(
            "POST",
            "/api/alert-rules",
            json={"name": name, "condition_type": condition_type, "condition_config": condition_config, **kwargs},
        ).body

    def get(self, id: str) -> dict[str, Any]:
        return self._c._request("GET", f"/api/alert-rules/{id}").body

    def update(self, id: str, **kwargs: Any) -> dict[str, Any]:
        return self._c._request("PUT", f"/api/alert-rules/{id}", json=kwargs).body

    def delete(self, id: str) -> dict[str, Any]:
        return self._c._request("DELETE", f"/api/alert-rules/{id}").body

    def enable(self, id: str) -> dict[str, Any]:
        return self._c._request("POST", f"/api/alert-rules/{id}/enable").body

    def disable(self, id: str) -> dict[str, Any]:
        return self._c._request("POST", f"/api/alert-rules/{id}/disable").body


class AnalyticsResource:
    def __init__(self, client: Admin) -> None:
        self._c = client

    def costs(
        self,
        *,
        group_by: str,
        agent_id: str | None = None,
        provider: str | None = None,
        model: str | None = None,
        since: str | None = None,
        until: str | None = None,
        granularity: str | None = None,
        limit: int | None = None,
        offset: int | None = None,
    ) -> dict[str, Any]:
        return self._c._request(
            "GET",
            "/api/analytics/costs",
            params={
                "group_by": group_by,
                "agent_id": agent_id,
                "provider": provider,
                "model": model,
                "since": since,
                "until": until,
                "granularity": granularity,
                "limit": limit,
                "offset": offset,
            },
        ).body

    def latency(
        self,
        *,
        group_by: str,
        agent_id: str | None = None,
        provider: str | None = None,
        model: str | None = None,
        since: str | None = None,
        until: str | None = None,
        granularity: str | None = None,
        limit: int | None = None,
        offset: int | None = None,
    ) -> dict[str, Any]:
        return self._c._request(
            "GET",
            "/api/analytics/latency",
            params={
                "group_by": group_by,
                "agent_id": agent_id,
                "provider": provider,
                "model": model,
                "since": since,
                "until": until,
                "granularity": granularity,
                "limit": limit,
                "offset": offset,
            },
        ).body

    def errors(
        self,
        *,
        group_by: str,
        agent_id: str | None = None,
        provider: str | None = None,
        model: str | None = None,
        since: str | None = None,
        until: str | None = None,
        granularity: str | None = None,
        limit: int | None = None,
        offset: int | None = None,
    ) -> dict[str, Any]:
        return self._c._request(
            "GET",
            "/api/analytics/errors",
            params={
                "group_by": group_by,
                "agent_id": agent_id,
                "provider": provider,
                "model": model,
                "since": since,
                "until": until,
                "granularity": granularity,
                "limit": limit,
                "offset": offset,
            },
        ).body

    def throughput(
        self,
        *,
        group_by: str,
        agent_id: str | None = None,
        provider: str | None = None,
        model: str | None = None,
        since: str | None = None,
        until: str | None = None,
        granularity: str | None = None,
        limit: int | None = None,
        offset: int | None = None,
    ) -> dict[str, Any]:
        return self._c._request(
            "GET",
            "/api/analytics/throughput",
            params={
                "group_by": group_by,
                "agent_id": agent_id,
                "provider": provider,
                "model": model,
                "since": since,
                "until": until,
                "granularity": granularity,
                "limit": limit,
                "offset": offset,
            },
        ).body

    def provider_reliability(
        self,
        *,
        agent_id: str | None = None,
        since: str | None = None,
        until: str | None = None,
        limit: int | None = None,
        offset: int | None = None,
    ) -> dict[str, Any]:
        return self._c._request(
            "GET",
            "/api/analytics/provider-reliability",
            params={"agent_id": agent_id, "since": since, "until": until, "limit": limit, "offset": offset},
        ).body

    def runs(
        self,
        *,
        agent_id: str | None = None,
        since: str | None = None,
        until: str | None = None,
        granularity: str | None = None,
        limit: int | None = None,
        offset: int | None = None,
    ) -> dict[str, Any]:
        return self._c._request(
            "GET",
            "/api/analytics/runs",
            params={
                "agent_id": agent_id,
                "since": since,
                "until": until,
                "granularity": granularity,
                "limit": limit,
                "offset": offset,
            },
        ).body

    def top(
        self,
        *,
        metric: str,
        entity: str,
        since: str | None = None,
        until: str | None = None,
        limit: int | None = None,
    ) -> dict[str, Any]:
        return self._c._request(
            "GET",
            "/api/analytics/top",
            params={"metric": metric, "entity": entity, "since": since, "until": until, "limit": limit},
        ).body

    def overview(self) -> dict[str, Any]:
        return self._c._request("GET", "/api/overview/stats").body

    def cleanup_preview(self, *, days: int = 30) -> dict[str, Any]:
        return self._c._request("GET", "/api/analytics/cleanup-preview", params={"days": days}).body

    def cleanup(self, *, days: int) -> dict[str, Any]:
        return self._c._request("POST", "/api/analytics/cleanup", json={"days": days}).body


class ProvidersResource:
    def __init__(self, client: Admin) -> None:
        self._c = client

    def health(self) -> dict[str, Any]:
        return self._c._request("GET", "/api/providers/health").body


# ─── Resource Classes (Async) ────────────────────────────


class AsyncProviderKeysResource:
    def __init__(self, client: AsyncAdmin) -> None:
        self._c = client

    async def list(self, *, provider: str | None = None, status: str | None = None) -> dict[str, Any]:
        return (
            await self._c._request("GET", "/api/provider-keys", params={"provider": provider, "status": status})
        ).body

    async def create(self, *, provider: str, name: str, api_key: str, **kwargs: Any) -> dict[str, Any]:
        return (
            await self._c._request(
                "POST", "/api/provider-keys", json={"provider": provider, "name": name, "api_key": api_key, **kwargs}
            )
        ).body

    async def get(self, id: str) -> dict[str, Any]:
        return (await self._c._request("GET", f"/api/provider-keys/{id}")).body

    async def update(self, id: str, **kwargs: Any) -> dict[str, Any]:
        return (await self._c._request("PUT", f"/api/provider-keys/{id}", json=kwargs)).body

    async def delete(self, id: str) -> dict[str, Any]:
        return (await self._c._request("DELETE", f"/api/provider-keys/{id}")).body

    async def upsert(self, name: str, **kwargs: Any) -> dict[str, Any]:
        return (await self._c._request("PUT", f"/api/provider-keys/by-name/{name}", json=kwargs)).body


class AsyncPoliciesResource:
    def __init__(self, client: AsyncAdmin) -> None:
        self._c = client

    async def list(self, *, name: str | None = None) -> dict[str, Any]:
        return (await self._c._request("GET", "/api/policies", params={"name": name})).body

    async def create(self, *, name: str, **kwargs: Any) -> dict[str, Any]:
        return (await self._c._request("POST", "/api/policies", json={"name": name, **kwargs})).body

    async def get(self, id: str) -> dict[str, Any]:
        return (await self._c._request("GET", f"/api/policies/{id}")).body

    async def update(self, id: str, **kwargs: Any) -> dict[str, Any]:
        return (await self._c._request("PUT", f"/api/policies/{id}", json=kwargs)).body

    async def delete(self, id: str) -> dict[str, Any]:
        return (await self._c._request("DELETE", f"/api/policies/{id}")).body

    async def upsert(self, name: str, **kwargs: Any) -> dict[str, Any]:
        return (await self._c._request("PUT", f"/api/policies/by-name/{name}", json=kwargs)).body

    async def versions(self, id: str) -> dict[str, Any]:
        return (await self._c._request("GET", f"/api/policies/{id}/versions")).body

    async def version(self, id: str, version_number: int) -> dict[str, Any]:
        return (await self._c._request("GET", f"/api/policies/{id}/versions/{version_number}")).body


class AsyncAgentsResource:
    def __init__(self, client: AsyncAdmin) -> None:
        self._c = client

    async def list(self, *, status: str | None = None, policy_id: str | None = None) -> dict[str, Any]:
        return (await self._c._request("GET", "/api/agents", params={"status": status, "policy_id": policy_id})).body

    async def create(self, *, name: str, policy_id: str, **kwargs: Any) -> dict[str, Any]:
        return (
            await self._c._request("POST", "/api/agents", json={"name": name, "policy_id": policy_id, **kwargs})
        ).body

    async def get(self, id: str) -> dict[str, Any]:
        return (await self._c._request("GET", f"/api/agents/{id}")).body

    async def update(self, id: str, **kwargs: Any) -> dict[str, Any]:
        return (await self._c._request("PUT", f"/api/agents/{id}", json=kwargs)).body

    async def patch(self, id: str, **kwargs: Any) -> dict[str, Any]:
        return (await self._c._request("PATCH", f"/api/agents/{id}", json=kwargs)).body

    async def rotate_key(self, id: str) -> dict[str, Any]:
        return (await self._c._request("POST", f"/api/agents/{id}/rotate-key")).body

    async def upsert(self, name: str, **kwargs: Any) -> dict[str, Any]:
        return (await self._c._request("PUT", f"/api/agents/by-name/{name}", json=kwargs)).body

    async def stats(self) -> dict[str, Any]:
        return (await self._c._request("GET", "/api/agents/stats/all")).body


class AsyncRunsResource:
    def __init__(self, client: AsyncAdmin) -> None:
        self._c = client

    async def list(
        self,
        *,
        agent_id: str | None = None,
        status: str | None = None,
        since: str | None = None,
        until: str | None = None,
        sort: str | None = None,
        order: str | None = None,
        limit: int | None = None,
        offset: int | None = None,
    ) -> dict[str, Any]:
        return (
            await self._c._request(
                "GET",
                "/api/runs",
                params={
                    "agent_id": agent_id,
                    "status": status,
                    "since": since,
                    "until": until,
                    "sort": sort,
                    "order": order,
                    "limit": limit,
                    "offset": offset,
                },
            )
        ).body

    async def get(self, id: str) -> dict[str, Any]:
        return (await self._c._request("GET", f"/api/runs/{id}")).body

    async def steps(
        self,
        id: str,
        *,
        sort: str | None = None,
        order: str | None = None,
        limit: int | None = None,
        offset: int | None = None,
    ) -> dict[str, Any]:
        return (
            await self._c._request(
                "GET", f"/api/runs/{id}/steps", params={"sort": sort, "order": order, "limit": limit, "offset": offset}
            )
        ).body

    async def ledger(self, id: str) -> dict[str, Any]:
        return (await self._c._request("GET", f"/api/runs/{id}/ledger")).body

    async def stop(self, id: str) -> dict[str, Any]:
        return (await self._c._request("POST", f"/api/runs/{id}/stop")).body


class AsyncWebhooksResource:
    def __init__(self, client: AsyncAdmin) -> None:
        self._c = client

    async def list(self, *, status: str | None = None, event: str | None = None) -> dict[str, Any]:
        return (await self._c._request("GET", "/api/webhooks", params={"status": status, "event": event})).body

    async def create(self, *, name: str, url: str, events: list[str], **kwargs: Any) -> dict[str, Any]:
        return (
            await self._c._request("POST", "/api/webhooks", json={"name": name, "url": url, "events": events, **kwargs})
        ).body

    async def get(self, id: str) -> dict[str, Any]:
        return (await self._c._request("GET", f"/api/webhooks/{id}")).body

    async def update(self, id: str, **kwargs: Any) -> dict[str, Any]:
        return (await self._c._request("PUT", f"/api/webhooks/{id}", json=kwargs)).body

    async def delete(self, id: str) -> dict[str, Any]:
        return (await self._c._request("DELETE", f"/api/webhooks/{id}")).body

    async def deliveries(
        self,
        id: str,
        *,
        status: str | None = None,
        event_type: str | None = None,
        limit: int | None = None,
        offset: int | None = None,
    ) -> dict[str, Any]:
        return (
            await self._c._request(
                "GET",
                f"/api/webhooks/{id}/deliveries",
                params={"status": status, "event_type": event_type, "limit": limit, "offset": offset},
            )
        ).body

    async def test(self, id: str) -> dict[str, Any]:
        return (await self._c._request("POST", f"/api/webhooks/{id}/test")).body

    async def enable(self, id: str) -> dict[str, Any]:
        return (await self._c._request("POST", f"/api/webhooks/{id}/enable")).body

    async def disable(self, id: str) -> dict[str, Any]:
        return (await self._c._request("POST", f"/api/webhooks/{id}/disable")).body


class AsyncTokensResource:
    def __init__(self, client: AsyncAdmin) -> None:
        self._c = client

    async def list(self, *, status: str | None = None) -> dict[str, Any]:
        return (await self._c._request("GET", "/api/admin-tokens", params={"status": status})).body

    async def create(self, *, name: str, scopes: list[str], **kwargs: Any) -> dict[str, Any]:
        return (
            await self._c._request("POST", "/api/admin-tokens", json={"name": name, "scopes": scopes, **kwargs})
        ).body

    async def get(self, id: str) -> dict[str, Any]:
        return (await self._c._request("GET", f"/api/admin-tokens/{id}")).body

    async def revoke(self, id: str) -> dict[str, Any]:
        return (await self._c._request("POST", f"/api/admin-tokens/{id}/revoke")).body


class AsyncApprovalsResource:
    def __init__(self, client: AsyncAdmin) -> None:
        self._c = client

    async def list(
        self, *, agent_id: str | None = None, run_id: str | None = None, status: str | None = None
    ) -> dict[str, Any]:
        return (
            await self._c._request(
                "GET", "/api/approval-requests", params={"agent_id": agent_id, "run_id": run_id, "status": status}
            )
        ).body

    async def get(self, id: str) -> dict[str, Any]:
        return (await self._c._request("GET", f"/api/approval-requests/{id}")).body

    async def approve(self, id: str) -> dict[str, Any]:
        return (await self._c._request("POST", f"/api/approval-requests/{id}/approve")).body

    async def reject(self, id: str, *, reason: str | None = None) -> dict[str, Any]:
        body: dict[str, Any] = {}
        if reason is not None:
            body["reason"] = reason
        return (await self._c._request("POST", f"/api/approval-requests/{id}/reject", json=body)).body


class AsyncAlertRulesResource:
    def __init__(self, client: AsyncAdmin) -> None:
        self._c = client

    async def list(
        self, *, agent_id: str | None = None, condition_type: str | None = None, status: str | None = None
    ) -> dict[str, Any]:
        return (
            await self._c._request(
                "GET",
                "/api/alert-rules",
                params={"agent_id": agent_id, "condition_type": condition_type, "status": status},
            )
        ).body

    async def create(
        self, *, name: str, condition_type: str, condition_config: dict[str, Any], **kwargs: Any
    ) -> dict[str, Any]:
        return (
            await self._c._request(
                "POST",
                "/api/alert-rules",
                json={"name": name, "condition_type": condition_type, "condition_config": condition_config, **kwargs},
            )
        ).body

    async def get(self, id: str) -> dict[str, Any]:
        return (await self._c._request("GET", f"/api/alert-rules/{id}")).body

    async def update(self, id: str, **kwargs: Any) -> dict[str, Any]:
        return (await self._c._request("PUT", f"/api/alert-rules/{id}", json=kwargs)).body

    async def delete(self, id: str) -> dict[str, Any]:
        return (await self._c._request("DELETE", f"/api/alert-rules/{id}")).body

    async def enable(self, id: str) -> dict[str, Any]:
        return (await self._c._request("POST", f"/api/alert-rules/{id}/enable")).body

    async def disable(self, id: str) -> dict[str, Any]:
        return (await self._c._request("POST", f"/api/alert-rules/{id}/disable")).body


class AsyncAnalyticsResource:
    def __init__(self, client: AsyncAdmin) -> None:
        self._c = client

    async def costs(
        self,
        *,
        group_by: str,
        agent_id: str | None = None,
        provider: str | None = None,
        model: str | None = None,
        since: str | None = None,
        until: str | None = None,
        granularity: str | None = None,
        limit: int | None = None,
        offset: int | None = None,
    ) -> dict[str, Any]:
        return (
            await self._c._request(
                "GET",
                "/api/analytics/costs",
                params={
                    "group_by": group_by,
                    "agent_id": agent_id,
                    "provider": provider,
                    "model": model,
                    "since": since,
                    "until": until,
                    "granularity": granularity,
                    "limit": limit,
                    "offset": offset,
                },
            )
        ).body

    async def latency(
        self,
        *,
        group_by: str,
        agent_id: str | None = None,
        provider: str | None = None,
        model: str | None = None,
        since: str | None = None,
        until: str | None = None,
        granularity: str | None = None,
        limit: int | None = None,
        offset: int | None = None,
    ) -> dict[str, Any]:
        return (
            await self._c._request(
                "GET",
                "/api/analytics/latency",
                params={
                    "group_by": group_by,
                    "agent_id": agent_id,
                    "provider": provider,
                    "model": model,
                    "since": since,
                    "until": until,
                    "granularity": granularity,
                    "limit": limit,
                    "offset": offset,
                },
            )
        ).body

    async def errors(
        self,
        *,
        group_by: str,
        agent_id: str | None = None,
        provider: str | None = None,
        model: str | None = None,
        since: str | None = None,
        until: str | None = None,
        granularity: str | None = None,
        limit: int | None = None,
        offset: int | None = None,
    ) -> dict[str, Any]:
        return (
            await self._c._request(
                "GET",
                "/api/analytics/errors",
                params={
                    "group_by": group_by,
                    "agent_id": agent_id,
                    "provider": provider,
                    "model": model,
                    "since": since,
                    "until": until,
                    "granularity": granularity,
                    "limit": limit,
                    "offset": offset,
                },
            )
        ).body

    async def throughput(
        self,
        *,
        group_by: str,
        agent_id: str | None = None,
        provider: str | None = None,
        model: str | None = None,
        since: str | None = None,
        until: str | None = None,
        granularity: str | None = None,
        limit: int | None = None,
        offset: int | None = None,
    ) -> dict[str, Any]:
        return (
            await self._c._request(
                "GET",
                "/api/analytics/throughput",
                params={
                    "group_by": group_by,
                    "agent_id": agent_id,
                    "provider": provider,
                    "model": model,
                    "since": since,
                    "until": until,
                    "granularity": granularity,
                    "limit": limit,
                    "offset": offset,
                },
            )
        ).body

    async def provider_reliability(
        self,
        *,
        agent_id: str | None = None,
        since: str | None = None,
        until: str | None = None,
        limit: int | None = None,
        offset: int | None = None,
    ) -> dict[str, Any]:
        return (
            await self._c._request(
                "GET",
                "/api/analytics/provider-reliability",
                params={"agent_id": agent_id, "since": since, "until": until, "limit": limit, "offset": offset},
            )
        ).body

    async def runs(
        self,
        *,
        agent_id: str | None = None,
        since: str | None = None,
        until: str | None = None,
        granularity: str | None = None,
        limit: int | None = None,
        offset: int | None = None,
    ) -> dict[str, Any]:
        return (
            await self._c._request(
                "GET",
                "/api/analytics/runs",
                params={
                    "agent_id": agent_id,
                    "since": since,
                    "until": until,
                    "granularity": granularity,
                    "limit": limit,
                    "offset": offset,
                },
            )
        ).body

    async def top(
        self,
        *,
        metric: str,
        entity: str,
        since: str | None = None,
        until: str | None = None,
        limit: int | None = None,
    ) -> dict[str, Any]:
        return (
            await self._c._request(
                "GET",
                "/api/analytics/top",
                params={"metric": metric, "entity": entity, "since": since, "until": until, "limit": limit},
            )
        ).body

    async def overview(self) -> dict[str, Any]:
        return (await self._c._request("GET", "/api/overview/stats")).body

    async def cleanup_preview(self, *, days: int = 30) -> dict[str, Any]:
        return (await self._c._request("GET", "/api/analytics/cleanup-preview", params={"days": days})).body

    async def cleanup(self, *, days: int) -> dict[str, Any]:
        return (await self._c._request("POST", "/api/analytics/cleanup", json={"days": days})).body


class AsyncProvidersResource:
    def __init__(self, client: AsyncAdmin) -> None:
        self._c = client

    async def health(self) -> dict[str, Any]:
        return (await self._c._request("GET", "/api/providers/health")).body
