"""Monitors resource — /monitors endpoints."""

from __future__ import annotations

from typing import TYPE_CHECKING, Any

from curvestone.types.job import JobCreated
from curvestone.types.monitor import Monitor, MonitorList

if TYPE_CHECKING:
    from curvestone._client import AsyncCurvestone, Curvestone


class SyncMonitors:
    def __init__(self, client: Curvestone) -> None:
        self._client = client

    def create(
        self,
        *,
        targets: list[dict[str, Any]],
        schedule: dict[str, Any],
        brokerage: str | None = None,
    ) -> Monitor:
        """Create a new monitor."""
        body: dict[str, Any] = {"targets": targets, "schedule": schedule}
        if brokerage is not None:
            body["brokerage"] = brokerage
        resp = self._client._request("POST", "/monitor", json=body)
        return Monitor.model_validate(resp)

    def retrieve(self, monitor_id: str) -> Monitor:
        """Get a monitor by ID."""
        resp = self._client._request("GET", f"/monitors/{monitor_id}")
        return Monitor.model_validate(resp)

    def list(
        self,
        *,
        limit: int = 20,
        starting_after: str | None = None,
    ) -> MonitorList:
        """List monitors."""
        resp = self._client._request(
            "GET",
            "/monitors",
            params={"limit": limit, "starting_after": starting_after},
        )
        return MonitorList.model_validate(resp)

    def update(
        self,
        monitor_id: str,
        *,
        targets: list[dict[str, Any]] | None = None,
        schedule: dict[str, Any] | None = None,
    ) -> Monitor:
        """Update a monitor."""
        body: dict[str, Any] = {}
        if targets is not None:
            body["targets"] = targets
        if schedule is not None:
            body["schedule"] = schedule
        resp = self._client._request("PATCH", f"/monitors/{monitor_id}", json=body)
        return Monitor.model_validate(resp)

    def delete(self, monitor_id: str) -> None:
        """Delete a monitor."""
        self._client._request("DELETE", f"/monitors/{monitor_id}")

    def run(self, monitor_id: str) -> JobCreated:
        """Trigger a monitor run."""
        resp = self._client._request("POST", f"/monitors/{monitor_id}/run")
        return JobCreated.model_validate(resp)


class AsyncMonitors:
    def __init__(self, client: AsyncCurvestone) -> None:
        self._client = client

    async def create(
        self,
        *,
        targets: list[dict[str, Any]],
        schedule: dict[str, Any],
        brokerage: str | None = None,
    ) -> Monitor:
        """Create a new monitor."""
        body: dict[str, Any] = {"targets": targets, "schedule": schedule}
        if brokerage is not None:
            body["brokerage"] = brokerage
        resp = await self._client._request("POST", "/monitor", json=body)
        return Monitor.model_validate(resp)

    async def retrieve(self, monitor_id: str) -> Monitor:
        """Get a monitor by ID."""
        resp = await self._client._request("GET", f"/monitors/{monitor_id}")
        return Monitor.model_validate(resp)

    async def list(
        self,
        *,
        limit: int = 20,
        starting_after: str | None = None,
    ) -> MonitorList:
        """List monitors."""
        resp = await self._client._request(
            "GET",
            "/monitors",
            params={"limit": limit, "starting_after": starting_after},
        )
        return MonitorList.model_validate(resp)

    async def update(
        self,
        monitor_id: str,
        *,
        targets: list[dict[str, Any]] | None = None,
        schedule: dict[str, Any] | None = None,
    ) -> Monitor:
        """Update a monitor."""
        body: dict[str, Any] = {}
        if targets is not None:
            body["targets"] = targets
        if schedule is not None:
            body["schedule"] = schedule
        resp = await self._client._request("PATCH", f"/monitors/{monitor_id}", json=body)
        return Monitor.model_validate(resp)

    async def delete(self, monitor_id: str) -> None:
        """Delete a monitor."""
        await self._client._request("DELETE", f"/monitors/{monitor_id}")

    async def run(self, monitor_id: str) -> JobCreated:
        """Trigger a monitor run."""
        resp = await self._client._request("POST", f"/monitors/{monitor_id}/run")
        return JobCreated.model_validate(resp)
