# Copyright (c) 2025 Patrick Motsch
# All rights reserved.
"""Cross-workflow tools and core-only tool-set tagging."""

import logging
from typing import Any, Dict, List, Optional

from modules.serviceCenter.services.serviceAgent.datamodelAgent import ToolResult
from modules.serviceCenter.services.serviceAgent.toolRegistry import ToolRegistry

from modules.serviceCenter.services.serviceAgent.coreTools._helpers import (
    _getOrCreateTempFolder,
    _looksLikeBinary,
    _resolveFileScope,
    _MAX_TOOL_RESULT_CHARS,
)

logger = logging.getLogger(__name__)


def _registerCrossWorkflowTools(registry: ToolRegistry, services):
    """Auto-extracted from registerCoreTools."""
    # ---- Cross-workflow tools ----

    async def _listWorkflowHistory(args: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        """List all chat workflows in this workspace with metadata."""
        import json as _json
        try:
            chatService = services.chat
            chatInterface = chatService.interfaceDbChat
            allWorkflows = chatInterface.getWorkflows() or []

            allWorkflows.sort(
                key=lambda w: w.get("sysCreatedAt") or w.get("startedAt") or 0,
                reverse=True,
            )
            allWorkflows = allWorkflows[:50]

            items = []
            for wf in allWorkflows:
                wfId = wf.get("id", "")
                name = wf.get("name") or "(unnamed)"
                createdAt = wf.get("sysCreatedAt") or wf.get("startedAt") or 0
                lastActivity = wf.get("lastActivity") or createdAt

                msgs = chatInterface.getMessages(wfId) or []
                messageCount = len(msgs)
                lastPreview = ""
                if msgs:
                    lastMsg = msgs[-1] if isinstance(msgs[-1], dict) else (
                        msgs[-1].model_dump() if hasattr(msgs[-1], "model_dump") else {}
                    )
                    content = lastMsg.get("message") or lastMsg.get("content") or ""
                    lastPreview = content[:150]

                items.append({
                    "id": wfId,
                    "name": name,
                    "createdAt": createdAt,
                    "lastActivity": lastActivity,
                    "messageCount": messageCount,
                    "lastMessagePreview": lastPreview,
                })

            return ToolResult(
                toolCallId="", toolName="listWorkflowHistory",
                success=True, data=_json.dumps(items, ensure_ascii=False),
            )
        except Exception as e:
            return ToolResult(
                toolCallId="", toolName="listWorkflowHistory",
                success=False, error=str(e),
            )

    registry.register(
        "listWorkflowHistory", _listWorkflowHistory,
        description=(
            "List all chat conversations/workflows in this workspace. "
            "Returns id, name, createdAt, lastActivity, messageCount, and a preview "
            "of the last message for each workflow. Use this to discover previous "
            "conversations when the user asks about past chats or wants a summary "
            "across conversations."
        ),
        parameters={
            "type": "object",
            "properties": {},
        },
        readOnly=True,
    )

    async def _readWorkflowMessages(args: Dict[str, Any], context: Dict[str, Any]) -> ToolResult:
        """Read messages from a specific workflow."""
        import json as _json
        targetWorkflowId = args.get("workflowId", "")
        limit = int(args.get("limit", 20))
        offset = int(args.get("offset", 0))

        if not targetWorkflowId:
            return ToolResult(
                toolCallId="", toolName="readWorkflowMessages",
                success=False, error="workflowId is required",
            )

        try:
            chatService = services.chat
            chatInterface = chatService.interfaceDbChat
            allMsgs = chatInterface.getMessages(targetWorkflowId) or []

            sliced = allMsgs[offset:offset + limit]
            items = []
            for msg in sliced:
                raw = msg if isinstance(msg, dict) else (
                    msg.model_dump() if hasattr(msg, "model_dump") else {}
                )
                content = raw.get("message") or raw.get("content") or ""
                if len(content) > 2000:
                    content = content[:2000] + "..."
                items.append({
                    "role": raw.get("role", ""),
                    "message": content,
                    "publishedAt": raw.get("publishedAt") or raw.get("sysCreatedAt") or 0,
                })

            header = f"Workflow {targetWorkflowId}: {len(allMsgs)} total messages"
            if offset > 0 or len(allMsgs) > offset + limit:
                header += f" (showing {offset + 1}-{offset + len(sliced)})"

            return ToolResult(
                toolCallId="", toolName="readWorkflowMessages",
                success=True,
                data=header + "\n" + _json.dumps(items, ensure_ascii=False),
            )
        except Exception as e:
            return ToolResult(
                toolCallId="", toolName="readWorkflowMessages",
                success=False, error=str(e),
            )

    registry.register(
        "readWorkflowMessages", _readWorkflowMessages,
        description=(
            "Read messages from a specific chat workflow/conversation. "
            "Use this after listWorkflowHistory to read the content of a "
            "specific past conversation. Supports pagination via offset/limit."
        ),
        parameters={
            "type": "object",
            "properties": {
                "workflowId": {"type": "string", "description": "ID of the workflow to read messages from"},
                "limit": {"type": "integer", "description": "Max messages to return (default 20)"},
                "offset": {"type": "integer", "description": "Skip first N messages (default 0)"},
            },
            "required": ["workflowId"],
        },
        readOnly=True,
    )

    # Tag core-only tools so restricted toolSets (e.g. "commcoach") exclude them.
    # Tools NOT in this set remain toolSet=None → available to ALL sets.
    _CORE_ONLY_TOOLS = {
        "listFiles", "listFolders", "tagFile", "moveFile", "createFolder",
        "writeFile", "deleteFile", "renameFile", "translateText",
        "deleteFolder", "renameFolder", "moveFolder", "copyFile", "replaceInFile",
        "listConnections", "uploadToExternal", "sendMail", "downloadFromDataSource",
        "browseContainer", "readContentObjects", "extractContainerItem",
        "summarizeContent", "describeImage", "renderDocument",
        "textToSpeech", "generateImage", "createChart",
        "speechToText", "detectLanguage", "neutralizeData", "executeCode",
        "listWorkflowHistory", "readWorkflowMessages",
    }
    for _toolName in _CORE_ONLY_TOOLS:
        _td = registry.getTool(_toolName)
        if _td:
            _td.toolSet = "core"

