"""HTTP client for the Mesh Cognition service."""

from __future__ import annotations

import json
import urllib.request
import urllib.error
from typing import Any, Optional


class MeshCognitionAPIWrapper:
    """Wrapper for the mesh-cognition-service HTTP API.

    The mesh service runs locally and provides shared memory across devices.
    Install and start it with:
        npm install -g mesh-cognition-service
        mesh-cognition start --daemon
    """

    def __init__(self, base_url: str = "http://127.0.0.1:18790"):
        self.base_url = base_url.rstrip("/")

    def _get(self, path: str) -> dict[str, Any]:
        url = f"{self.base_url}{path}"
        req = urllib.request.Request(url)
        try:
            with urllib.request.urlopen(req, timeout=5) as resp:
                return json.loads(resp.read().decode())
        except urllib.error.URLError as e:
            raise ConnectionError(
                f"Mesh service not reachable at {self.base_url}. "
                f"Start it with: mesh-cognition start --daemon"
            ) from e

    def _post(self, path: str, data: dict[str, Any]) -> dict[str, Any]:
        url = f"{self.base_url}{path}"
        payload = json.dumps(data).encode()
        req = urllib.request.Request(
            url, data=payload, method="POST",
            headers={"Content-Type": "application/json"},
        )
        try:
            with urllib.request.urlopen(req, timeout=5) as resp:
                return json.loads(resp.read().decode())
        except urllib.error.URLError as e:
            raise ConnectionError(
                f"Mesh service not reachable at {self.base_url}. "
                f"Start it with: mesh-cognition start --daemon"
            ) from e

    def write_memory(self, content: str, key: Optional[str] = None, tags: Optional[list[str]] = None) -> dict:
        """Write a memory entry and broadcast to all mesh peers."""
        data: dict[str, Any] = {"content": content}
        if key:
            data["key"] = key
        if tags:
            data["tags"] = tags
        return self._post("/memory", data)

    def search_memory(self, query: str) -> list[dict]:
        """Search local and peer memories by keyword."""
        result = self._get(f"/memory/search?q={urllib.request.quote(query)}")
        return result.get("results", [])

    def status(self) -> dict:
        """Get mesh node status, peer count, and Kuramoto r(t)."""
        return self._get("/status")

    def peers(self) -> dict:
        """Get connected peers with coupling decisions."""
        return self._get("/peers")

    def context(self) -> dict:
        """Get mesh-influenced context from aligned peers."""
        return self._get("/context")

    def health(self) -> bool:
        """Check if the mesh service is running."""
        try:
            result = self._get("/health")
            return result.get("ok", False)
        except ConnectionError:
            return False
