"""AgentBill Agents Resource - CRUD operations with signal type assignment via unified HTTP client"""

from typing import Any, Dict, List, Optional
from ..http_client import AgentBillHTTPClient
from ..raw_response import WithRawResponseMixin
from ..logger import get_logger

_log = get_logger("agents")


class AgentsResource(WithRawResponseMixin):
    """
    Agents resource for CRUD operations and signal type management.

    All HTTP calls go through the shared ``AgentBillHTTPClient``.
    """

    _resource_path = "/functions/v1/api-agents"

    def __init__(self, config: Dict[str, Any], http_client: "AgentBillHTTPClient" = None):
        self.config = config
        self.debug = config.get("debug", False)
        self._http = http_client

    def list(self, status: Optional[str] = None) -> Dict[str, Any]:
        """List agents with optional status filter."""
        params = {}
        if status:
            params["status"] = status
        resp = self._http.get(self._resource_path, params=params)
        return resp.data

    def create(
        self,
        name: str,
        description: Optional[str] = None,
        agent_type: Optional[str] = None,
        model: Optional[str] = None,
        external_id: Optional[str] = None,
        metadata: Optional[Dict[str, Any]] = None,
        signal_type_names: Optional[List[str]] = None,
    ) -> Dict[str, Any]:
        """Create a new agent. Response includes a one-time visible API key."""
        payload: Dict[str, Any] = {"name": name}
        if description:
            payload["description"] = description
        if agent_type:
            payload["agent_type"] = agent_type
        if model:
            payload["model"] = model
        if external_id:
            payload["external_id"] = external_id
        if metadata:
            payload["metadata"] = metadata
        if signal_type_names:
            payload["signal_type_names"] = signal_type_names

        _log.debug("Creating agent: %s", name)
        resp = self._http.post(self._resource_path, json=payload)
        return resp.data

    def get(self, agent_id: str, by_external_id: bool = False) -> Dict[str, Any]:
        """Get an agent by ID or external_id."""
        params = {}
        if by_external_id:
            params["external_id"] = agent_id
        else:
            params["id"] = agent_id

        resp = self._http.get(self._resource_path, params=params)
        result = resp.data
        if "data" in result and isinstance(result["data"], list):
            if len(result["data"]) == 0:
                raise Exception("Agent not found")
            return result["data"][0]
        return result

    def update(
        self,
        agent_id: str,
        name: Optional[str] = None,
        description: Optional[str] = None,
        agent_type: Optional[str] = None,
        model: Optional[str] = None,
        status: Optional[str] = None,
        metadata: Optional[Dict[str, Any]] = None,
    ) -> Dict[str, Any]:
        """Update an agent."""
        payload: Dict[str, Any] = {"id": agent_id}
        if name:
            payload["name"] = name
        if description:
            payload["description"] = description
        if agent_type:
            payload["agent_type"] = agent_type
        if model:
            payload["model"] = model
        if status:
            payload["status"] = status
        if metadata:
            payload["metadata"] = metadata

        resp = self._http.patch(self._resource_path, json=payload)
        return resp.data

    def delete(self, agent_id: str) -> None:
        """Delete an agent."""
        self._http.request("DELETE", self._resource_path, json={"id": agent_id})

    def assign_signal_types(
        self,
        agent_id: Optional[str] = None,
        external_agent_id: Optional[str] = None,
        signal_type_ids: Optional[List[str]] = None,
        signal_type_names: Optional[List[str]] = None,
    ) -> Dict[str, Any]:
        """Assign signal types to an agent (explicit assignment)."""
        if not agent_id and not external_agent_id:
            raise ValueError("Either agent_id or external_agent_id is required")
        if not signal_type_ids and not signal_type_names:
            raise ValueError("Either signal_type_ids or signal_type_names is required")

        payload: Dict[str, Any] = {}
        if agent_id:
            payload["agent_id"] = agent_id
        if external_agent_id:
            payload["external_agent_id"] = external_agent_id
        if signal_type_ids:
            payload["signal_type_ids"] = signal_type_ids
        if signal_type_names:
            payload["signal_type_names"] = signal_type_names

        resp = self._http.post("/functions/v1/api-agent-signal-types", json=payload)
        return resp.data

    def get_signal_types(self, agent_id: str, by_external_id: bool = False) -> Dict[str, Any]:
        """Get signal types assigned to an agent."""
        params = {}
        if by_external_id:
            params["external_agent_id"] = agent_id
        else:
            params["agent_id"] = agent_id

        resp = self._http.get("/functions/v1/api-agent-signal-types", params=params)
        return resp.data

    def remove_signal_types(self, agent_id: str, signal_type_ids: Optional[List[str]] = None) -> None:
        """Remove signal types from an agent."""
        payload: Dict[str, Any] = {"agent_id": agent_id}
        if signal_type_ids:
            payload["signal_type_ids"] = signal_type_ids

        self._http.request("DELETE", "/functions/v1/api-agent-signal-types", json=payload)
