"""
HieromemMemoryBackend - AutoGen memory integration.

Provides persistent memory for AutoGen agents via HIEROMEM.
"""
from typing import Any, Dict, List, Optional
import httpx


class HieromemMemoryBackend:
    """
    Memory backend for AutoGen agents using HIEROMEM.

    Usage:
        from hieromem.integrations.autogen import HieromemMemoryBackend

        memory = HieromemMemoryBackend(
            hieromem_url="http://localhost:8000",
            agent_id="planner_agent",
            realm="project_alpha"
        )

        # In agent configuration
        assistant = AssistantAgent(
            name="assistant",
            system_message="...",
            llm_config=llm_config,
        )
        # Use memory.remember() and memory.recall()
    """

    def __init__(
        self,
        hieromem_url: str = "http://localhost:8000",
        api_key: Optional[str] = None,
        agent_id: str = "default_agent",
        realm: Optional[str] = None,
        namespace: str = "autogen",
    ) -> None:
        self.hieromem_url = hieromem_url
        self.api_key = api_key
        self.agent_id = agent_id
        self.realm = realm
        self.namespace = namespace
        self._client = httpx.Client(
            base_url=hieromem_url,
            headers={"Authorization": f"Bearer {api_key}"} if api_key else {},
            timeout=30.0,
        )

    def remember(
        self,
        content: str,
        meta: Optional[Dict[str, Any]] = None,
    ) -> Optional[str]:
        """
        Store a memory in HIEROMEM.

        Args:
            content: The content to remember
            meta: Additional metadata

        Returns:
            Episode ID if successful, None otherwise
        """
        payload = {
            "text": content,
            "namespace": self.namespace,
            "meta": {
                "agent_id": self.agent_id,
                "type": "autogen_memory",
                **(meta or {}),
            },
        }

        if self.realm:
            payload["realm"] = self.realm
            payload["agent"] = self.agent_id

        try:
            response = self._client.post("/memory/insert", json=payload)
            response.raise_for_status()
            result: Optional[str] = response.json().get("episode_id")
            return result
        except httpx.HTTPError:
            return None

    def recall(
        self,
        query: str,
        k: int = 5,
        min_confidence: float = 0.0,
    ) -> List[Dict[str, Any]]:
        """
        Retrieve memories from HIEROMEM.

        Args:
            query: Search query
            k: Number of results
            min_confidence: Minimum confidence threshold

        Returns:
            List of memory episodes
        """
        payload = {
            "query": query,
            "k": k,
            "namespace": self.namespace,
            "mode": "graph_hybrid",
            "min_confidence": min_confidence,
        }

        if self.realm:
            payload["realm"] = self.realm
            payload["agent"] = self.agent_id

        try:
            response = self._client.post("/memory/retrieve", json=payload)
            response.raise_for_status()
            episodes = response.json().get("episodes", [])
            return [
                {
                    "id": ep.get("id"),
                    "content": ep.get("meta", {}).get("text", ""),
                    "trust": ep.get("trust"),
                    "timestamp": ep.get("timestamp"),
                }
                for ep in episodes
            ]
        except httpx.HTTPError:
            return []

    def remember_conversation(
        self,
        sender: str,
        recipient: str,
        message: str,
    ) -> Optional[str]:
        """
        Store a conversation turn.

        Args:
            sender: Name of the sending agent
            recipient: Name of the receiving agent
            message: The message content

        Returns:
            Episode ID if successful
        """
        return self.remember(
            content=message,
            meta={
                "sender": sender,
                "recipient": recipient,
                "type": "conversation",
            },
        )

    def get_conversation_history(
        self,
        participants: Optional[List[str]] = None,
        limit: int = 20,
    ) -> List[Dict[str, Any]]:
        """
        Retrieve conversation history.

        Args:
            participants: Filter by participant names
            limit: Max number of messages

        Returns:
            List of conversation messages
        """
        query = "conversation history"
        if participants:
            query = f"conversation between {', '.join(participants)}"

        return self.recall(query, k=limit)

    def clear(self) -> bool:
        """Clear all memories for this agent."""
        try:
            self._client.delete(f"/memory/namespace/{self.namespace}")
            return True
        except httpx.HTTPError:
            return False

    def __del__(self) -> None:
        if hasattr(self, "_client") and self._client:
            self._client.close()
