"""Zo MCP client helpers — pull inbox and send messages via native MCP.

Mars M1d: Replace Cursor as the bridge to Zo. Used by ZoMessagingAdapter
with REST fallback when MCP fails.
"""

from __future__ import annotations

import json
import logging
from datetime import UTC, datetime
from typing import Any

from vastian.mcp.client import MCPClient
from vastian.mcp.providers import load_mcp_providers

logger = logging.getLogger(__name__)

ZO_INBOX_PATH = "/home/workspace/vastian-inbox"


def _zo_mcp_client(api_key: str) -> MCPClient | None:
    """Build MCP client for Zo if configured, enabled, and we have a key."""
    providers = load_mcp_providers()
    zo = providers.get("zo")
    if not zo or not zo.url or not api_key:
        return None
    return MCPClient(zo.url, headers={"Authorization": f"Bearer {api_key}"})


async def pull_inbox_via_mcp(api_key: str) -> list[dict[str, Any]]:
    """Pull messages from Zo vastian-inbox via MCP list_files + read_file.

    Returns empty list on MCP failure (caller should fall back to REST).
    """
    client = _zo_mcp_client(api_key)
    if not client:
        return []

    try:
        list_result = await client.call_tool("list_files", {"path": ZO_INBOX_PATH})
        if "error" in list_result:
            logger.debug("Zo MCP list_files failed: %s", list_result["error"])
            return []

        text = list_result.get("text", "")
        structured = list_result.get("structured", {})
        files_raw: list = []

        if isinstance(structured, dict) and "files" in structured:
            files_raw = structured.get("files", [])
        elif isinstance(structured, list):
            files_raw = structured
        elif text:
            try:
                parsed = json.loads(text)
                files_raw = (
                    parsed.get("files", [])
                    if isinstance(parsed, dict)
                    else (parsed if isinstance(parsed, list) else [])
                )
            except json.JSONDecodeError:
                files_raw = [
                    line.strip()
                    for line in text.splitlines()
                    if line.strip() and not line.startswith("0 entries")
                ]

        file_paths: list[str] = []
        for f in files_raw:
            if isinstance(f, str) and f and not f.startswith("."):
                file_paths.append(f)
            elif isinstance(f, dict):
                p = f.get("path") or f.get("name") or f.get("filename") or ""
                if p and not p.startswith("."):
                    file_paths.append(p)

        messages: list[dict[str, Any]] = []
        for fpath in file_paths:
            if not fpath or fpath.startswith("."):
                continue
            full_path = fpath if fpath.startswith("/") else f"{ZO_INBOX_PATH}/{fpath}"
            read_result = await client.call_tool(
                "read_file", {"target_file": full_path, "text_read_entire_file": True}
            )
            if "error" in read_result:
                logger.debug("Zo MCP read_file %s failed: %s", full_path, read_result["error"])
                continue
            content = read_result.get("text", "")
            messages.append(
                {
                    "id": fpath.split("/")[-1] if "/" in fpath else fpath,
                    "source": "zo",
                    "content": content,
                    "timestamp": datetime.now(UTC).isoformat(),
                    "type": "file",
                }
            )
        return messages
    except Exception as e:
        logger.debug("Zo MCP pull_inbox failed: %s", e)
        return []


async def send_sms_via_mcp(api_key: str, body: str) -> dict[str, Any]:
    """Send SMS via Zo MCP send_sms_to_user. Returns result or error dict."""
    client = _zo_mcp_client(api_key)
    if not client:
        return {"ok": False, "error": "Zo MCP not configured"}

    try:
        result = await client.call_tool("send_sms_to_user", {"message": body})
        if "error" in result:
            raise RuntimeError(result["error"])
        return {"ok": True, "message_id": "", "response": result.get("text", ""), "via": "mcp"}
    except Exception as e:
        logger.debug("Zo MCP send_sms failed: %s", e)
        raise


async def send_email_via_mcp(api_key: str, subject: str, body: str) -> dict[str, Any]:
    """Send email via Zo MCP send_email_to_user."""
    client = _zo_mcp_client(api_key)
    if not client:
        return {"ok": False, "error": "Zo MCP not configured"}

    try:
        result = await client.call_tool(
            "send_email_to_user", {"subject": subject, "markdown_body": body}
        )
        if "error" in result:
            raise RuntimeError(result["error"])
        return {"ok": True, "message_id": "", "response": result.get("text", ""), "via": "mcp"}
    except Exception as e:
        logger.debug("Zo MCP send_email failed: %s", e)
        raise
