"""
OpenClaw Adapter for OpenMemo.

Provides a memory backend for OpenClaw agent sessions.
Hooks into agent lifecycle events (thought, action, observation).

Usage (local):
    from openmemo.adapters.openclaw import OpenClawMemoryBackend
    backend = OpenClawMemoryBackend(agent_id="claw_agent")

Usage (remote):
    from openmemo.adapters.openclaw import OpenClawMemoryBackend
    backend = OpenClawMemoryBackend(
        agent_id="claw_agent",
        base_url="https://api.openmemo.ai",
    )
"""

from typing import List, Dict
from openmemo.adapters.base_adapter import BaseMemoryAdapter


class OpenClawMemoryBackend(BaseMemoryAdapter):
    adapter_name = "openclaw"

    def search_memory(self, query: str, scene: str = "",
                      limit: int = 10) -> List[Dict]:
        return self.recall_memory(query=query, scene=scene, limit=limit)

    def memory_governance(self, operation: str = "cleanup") -> dict:
        try:
            return self._memory.memory_governance(operation=operation)
        except Exception:
            return {"error": "governance failed"}

    def write(self, content: str, scene: str = "", cell_type: str = "fact") -> str:
        return self.write_memory(content=content, scene=scene, memory_type=cell_type)

    def recall(self, query: str, scene: str = "", mode: str = "kv",
               limit: int = 10) -> dict:
        return self.recall_context(query=query, scene=scene, mode=mode, limit=limit)

    def search(self, query: str, limit: int = 10) -> List[Dict]:
        return self.recall_memory(query=query, limit=limit)

    def on_thought(self, thought: str, scene: str = ""):
        pass

    def on_action(self, action: str, scene: str = ""):
        self.write_memory(content=action, scene=scene, memory_type="observation")

    def on_observation(self, observation: str, scene: str = ""):
        self.write_memory(content=observation, scene=scene, memory_type="observation")

    def on_agent_step(self, step_text: str, scene: str = "",
                      session_id: str = ""):
        """
        User Memory PRD §7.1 + Context Memory PRD §8.1
        + Orchestrator PRD §14 — Agent step hook.

        - Writes step to memory
        - Extracts user memory from step text
        - Records timeline event in context memory
        """
        self.write_memory(content=step_text, scene=scene, memory_type="observation")
        self.user_memory_store(step_text)
        # Context Memory: record as action event
        sid = session_id or self.conversation_id
        if sid:
            self.context_on_agent_step(sid, step_text)

    def build_orchestrated_prompt(self, task: str,
                                   session_id: str = "", **kwargs) -> dict:
        """
        PRD §14 — Orchestrator integration for on_agent_step.

        Returns full orchestration result.
        Use result["context"] as the injected system prompt.
        """
        return self.orchestrate_prompt(
            task=task,
            session_id=session_id,
            agent_role="openclaw",
            **kwargs
        )

    def on_tool_call(self, tool_name: str, result: str,
                     session_id: str = ""):
        """Context Memory PRD §8.1 — Tool call hook."""
        sid = session_id or self.conversation_id
        if sid and self._context_memory:
            try:
                self._context_memory.on_tool_call(sid, tool_name, result)
            except Exception:
                pass

    def on_message(self, role: str, content: str,
                   session_id: str = ""):
        """Context Memory PRD §12.1 — Message hook."""
        sid = session_id or self.conversation_id
        if sid:
            self.context_on_message(sid, role, content)

    def on_task_complete(self, task: str, result: str, scene: str = "",
                         session_id: str = ""):
        """
        User Memory PRD §7.1 + Context Memory PRD §7.1 / §12.1 — Task complete hook.

        - Writes decision to memory
        - Extracts user memory
        - Triggers context summary generation
        """
        content = f"{task}: {result}" if result else task
        self.write_memory(content=content, scene=scene, memory_type="decision")
        combined = f"{task}. {result}" if result else task
        self.user_memory_store(combined)
        # Context Memory: trigger summary on task complete
        sid = session_id or self.conversation_id
        if sid:
            self.context_on_task_complete(sid, task=task, result=result)
