import path from "path";
import os from "os";
import { isTextPart, isAssistantMessage, isToolMessage } from "@dexto/core";
import { supportsStartupInfo } from "../agent-backend.js";
const HIDDEN_TOOL_NAMES = /* @__PURE__ */ new Set(["wait_for"]);
function normalizeToolName(toolName) {
  if (toolName.startsWith("mcp--")) {
    const trimmed = toolName.substring("mcp--".length);
    const parts = trimmed.split("--");
    return parts.length >= 2 ? parts.slice(1).join("--") : trimmed;
  }
  return toolName;
}
function shouldHideTool(toolName) {
  if (!toolName) {
    return false;
  }
  return HIDDEN_TOOL_NAMES.has(normalizeToolName(toolName));
}
const backgroundCompletionRegex = /<background-task-completion>[\s\S]*?<\/background-task-completion>/g;
const stripBackgroundCompletion = (text) => text.replace(backgroundCompletionRegex, "").replace("<background-task-completion>", "").trim();
import { generateMessageId } from "./idGenerator.js";
const AUTOMATION_TRIGGER_REGEX = /<scheduled_automation_trigger>[\s\S]*?<\/scheduled_automation_trigger>/;
function extractAutomationTriggerInfo(content) {
  const match = content.match(AUTOMATION_TRIGGER_REGEX);
  if (!match) {
    return null;
  }
  const block = match[0];
  const taskMatch = block.match(/Task:\s*(.+)/i);
  const triggeredMatch = block.match(/Triggered at:\s*(.+)/i);
  const taskName = taskMatch?.[1]?.trim();
  const triggeredAt = triggeredMatch?.[1]?.trim() ?? null;
  return {
    label: taskName ? `\u23F0 Scheduled Task: ${taskName}` : "\u23F0 Scheduled Task",
    timestamp: triggeredAt,
    source: "scheduler"
  };
}
function stripAutomationTriggerTags(content) {
  const stripped = content.replace(
    /<scheduled_automation_trigger>[\s\S]*?<\/scheduled_automation_trigger>\s*/g,
    ""
  );
  return stripped === content ? content : stripped.trim();
}
function makeRelativePath(absolutePath, cwd = process.cwd()) {
  const normalizedPath = path.normalize(absolutePath);
  const normalizedCwd = path.normalize(cwd);
  const homeDir = os.homedir();
  if (normalizedPath.startsWith(normalizedCwd + path.sep) || normalizedPath === normalizedCwd) {
    const relative = path.relative(normalizedCwd, normalizedPath);
    return relative || ".";
  }
  if (normalizedPath.startsWith(homeDir + path.sep) || normalizedPath === homeDir) {
    return "~" + normalizedPath.slice(homeDir.length);
  }
  return absolutePath;
}
function formatPathForDisplay(absolutePath, maxWidth = 60, cwd = process.cwd()) {
  const relativePath = makeRelativePath(absolutePath, cwd);
  if (relativePath.length <= maxWidth) {
    return relativePath;
  }
  return centerTruncatePath(relativePath, maxWidth);
}
function centerTruncatePath(filePath, maxWidth) {
  if (filePath.length <= maxWidth) {
    return filePath;
  }
  const sep = path.sep;
  const segments = filePath.split(sep).filter(Boolean);
  if (segments.length <= 3) {
    return filePath.slice(0, maxWidth - 1) + "\u2026";
  }
  const first = filePath.startsWith(sep) ? sep + segments[0] : segments[0];
  const lastTwo = segments.slice(-2).join(sep);
  const truncated = `${first}${sep}\u2026${sep}${lastTwo}`;
  if (truncated.length <= maxWidth) {
    return truncated;
  }
  const filename = segments[segments.length - 1] || "";
  const withJustFilename = `\u2026${sep}${filename}`;
  if (withJustFilename.length <= maxWidth) {
    return withJustFilename;
  }
  return filename.slice(0, maxWidth - 1) + "\u2026";
}
function toTitleCase(name) {
  return name.replace(/[_-]+/g, " ").split(" ").filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
}
function getToolDisplayName(toolName) {
  if (toolName.startsWith("mcp--")) {
    const parts = toolName.split("--");
    if (parts.length >= 3) {
      return toTitleCase(parts.slice(2).join("--"));
    }
    return toTitleCase(toolName.substring(5));
  }
  return toTitleCase(toolName);
}
function getToolTypeBadge(toolName) {
  if (toolName.startsWith("mcp--")) {
    const parts = toolName.split("--");
    if (parts.length >= 3 && parts[1]) {
      return `MCP: ${parts[1]}`;
    }
    return "MCP";
  }
  return "local";
}
function formatToolHeader(options) {
  const { toolName, args, presentationSnapshot } = options;
  const snapshotHeader = presentationSnapshot?.header;
  const displayName = snapshotHeader?.title ?? getToolDisplayName(toolName);
  const argsFormatted = snapshotHeader?.argsText ?? formatArgsFallback(args);
  const badge = getToolTypeBadge(toolName);
  const isMcpTool = badge.startsWith("MCP");
  const badgeSuffix = isMcpTool ? ` [${badge}]` : "";
  const header = argsFormatted ? `${displayName}(${argsFormatted})${badgeSuffix}` : `${displayName}()${badgeSuffix}`;
  return {
    displayName,
    argsFormatted,
    badge,
    header
  };
}
function formatArgsFallback(args) {
  const entries = Object.entries(args).filter(([k]) => !["__meta", "description"].includes(k)).slice(0, 4);
  const str = entries.map(([k, v]) => {
    const val = typeof v === "string" ? v : JSON.stringify(v);
    return val.length > 50 ? `${k}=${val.slice(0, 47)}...` : `${k}=${val}`;
  }).join(", ");
  return str.length > 150 ? str.slice(0, 147) + "..." : str;
}
function createUserMessage(content) {
  return {
    id: generateMessageId("user"),
    role: "user",
    content,
    timestamp: /* @__PURE__ */ new Date()
  };
}
function createQueuedUserMessage(content, queuePosition) {
  return {
    id: generateMessageId("user-queued"),
    role: "user",
    content,
    timestamp: /* @__PURE__ */ new Date(),
    isQueued: true,
    queuePosition
  };
}
function createSystemMessage(content) {
  return {
    id: generateMessageId("system"),
    role: "system",
    content,
    timestamp: /* @__PURE__ */ new Date()
  };
}
function createErrorMessage(error) {
  const content = error instanceof Error ? error.message : error;
  return {
    id: generateMessageId("error"),
    role: "system",
    content: `Error: ${content}`,
    timestamp: /* @__PURE__ */ new Date()
  };
}
function createToolMessage(toolName) {
  return {
    id: generateMessageId("tool"),
    role: "tool",
    content: `\u{1F527} Calling tool: ${toolName}`,
    timestamp: /* @__PURE__ */ new Date()
  };
}
function createStreamingMessage() {
  return {
    id: generateMessageId("assistant"),
    role: "assistant",
    content: "",
    timestamp: /* @__PURE__ */ new Date(),
    isStreaming: true
  };
}
function extractTextContent(content) {
  if (!content) {
    return "";
  }
  return content.filter(isTextPart).map((part) => part.text).join("\n");
}
function formatToolResultPreview(result) {
  try {
    const parsed = JSON.parse(result);
    if (parsed.status === "running" && parsed.taskId) {
      return `Background task started (id: ${parsed.taskId})`;
    }
    if (parsed.found !== void 0 && parsed.taskId) {
      return parsed.found ? `Task ${parsed.taskId} status: ${parsed.status ?? "unknown"}` : `Task ${parsed.taskId} not found`;
    }
    if (Array.isArray(parsed.tasks) && typeof parsed.count === "number") {
      const running = parsed.tasks.filter((task) => task.status === "running").length;
      return `Tasks: ${parsed.count} total${running > 0 ? ` \u2022 ${running} running` : ""}`;
    }
  } catch {
  }
  const maxChars = 200;
  if (result.length <= maxChars) {
    return result;
  }
  return result.slice(0, maxChars) + "\u2026";
}
function generateToolResultPreview(content) {
  const textContent = extractTextContent(content);
  if (!textContent) return "";
  try {
    const parsed = JSON.parse(textContent);
    if (parsed.status === "running" && parsed.taskId) {
      return `Background task started (id: ${parsed.taskId})`;
    }
    if (Array.isArray(parsed.tasks) && typeof parsed.count === "number") {
      const running = parsed.tasks.filter((task) => task.status === "running").length;
      return `Tasks: ${parsed.count} total${running > 0 ? ` \u2022 ${running} running` : ""}`;
    }
    if (parsed.found !== void 0 && parsed.taskId) {
      return parsed.found ? `Task ${parsed.taskId} status: ${parsed.status ?? "unknown"}` : `Task ${parsed.taskId} not found`;
    }
  } catch {
  }
  const lines = textContent.split("\n");
  const previewLines = lines.slice(0, 5);
  let preview = previewLines.join("\n");
  if (preview.length > 400) {
    preview = preview.slice(0, 397) + "...";
  } else if (lines.length > 5) {
    preview += "\n...";
  }
  return preview;
}
function convertHistoryToUIMessages(history, sessionId) {
  const uiMessages = [];
  const toolCallMap = /* @__PURE__ */ new Map();
  for (const msg of history) {
    if (isAssistantMessage(msg) && msg.toolCalls) {
      for (const toolCall of msg.toolCalls) {
        toolCallMap.set(toolCall.id, toolCall);
      }
    }
  }
  history.forEach((msg, index) => {
    const timestamp = new Date(msg.timestamp ?? Date.now() - (history.length - index) * 1e3);
    if (isToolMessage(msg)) {
      if (shouldHideTool(msg.name)) {
        return;
      }
      const toolCall = toolCallMap.get(msg.toolCallId);
      const displayName = msg.presentationSnapshot?.header?.title ?? getToolDisplayName(msg.name);
      let toolContent = displayName;
      const snapshotArgsText = msg.presentationSnapshot?.header?.argsText;
      if (typeof snapshotArgsText === "string" && snapshotArgsText.length > 0) {
        toolContent = `${displayName}(${snapshotArgsText})`;
      }
      if (!snapshotArgsText && toolCall) {
        try {
          const args = JSON.parse(toolCall.function.arguments || "{}");
          const argsFormatted = formatArgsFallback(args);
          if (argsFormatted) {
            toolContent = `${displayName}(${argsFormatted})`;
          }
        } catch {
        }
      }
      const badge = getToolTypeBadge(msg.name);
      if (badge.startsWith("MCP")) {
        toolContent = `${toolContent} [${badge}]`;
      }
      const resultPreview = generateToolResultPreview(msg.content);
      uiMessages.push({
        id: `session-${sessionId}-${index}`,
        role: "tool",
        content: toolContent,
        timestamp,
        toolStatus: "finished",
        toolResult: resultPreview,
        isError: msg.success === false,
        // Store content parts for potential rich rendering
        toolContent: msg.content,
        // Restore structured display data for rich rendering (diffs, shell output, etc.)
        ...msg.displayData !== void 0 && {
          toolDisplayData: msg.displayData
        }
      });
      return;
    }
    if (isAssistantMessage(msg)) {
      let textContent2 = extractTextContent(msg.content);
      textContent2 = stripBackgroundCompletion(textContent2);
      if (!textContent2) return;
      uiMessages.push({
        id: `session-${sessionId}-${index}`,
        role: "assistant",
        content: textContent2,
        timestamp
      });
      return;
    }
    let textContent = extractTextContent(msg.content);
    textContent = stripBackgroundCompletion(textContent);
    if (!textContent) return;
    const automationTrigger = msg.role === "user" ? extractAutomationTriggerInfo(textContent) : null;
    if (automationTrigger) {
      uiMessages.push({
        id: `session-${sessionId}-${index}-trigger`,
        role: "system",
        content: automationTrigger.label,
        timestamp,
        styledType: "external-trigger",
        styledData: {
          label: automationTrigger.label,
          source: automationTrigger.source,
          timestamp: automationTrigger.timestamp ?? timestamp
        }
      });
      textContent = stripAutomationTriggerTags(textContent);
    }
    uiMessages.push({
      id: `session-${sessionId}-${index}`,
      role: msg.role,
      content: textContent,
      timestamp
    });
  });
  return uiMessages;
}
async function getStartupInfo(agent, sessionId) {
  if (!supportsStartupInfo(agent)) {
    return {
      connectedServers: {
        count: 0,
        names: []
      },
      failedConnections: [],
      toolCount: 0,
      logFile: null
    };
  }
  const connectedServers = agent.mcpManager.getClients();
  const failedConnections = agent.mcpManager.getFailedConnections();
  const tools = await agent.getAllTools();
  const toolCount = Object.keys(tools).length;
  const logFile = sessionId ? (await agent.getSession(sessionId))?.logger.getLogFilePath() ?? null : null;
  return {
    connectedServers: {
      count: connectedServers.size,
      names: Array.from(connectedServers.keys())
    },
    failedConnections: Object.keys(failedConnections),
    toolCount,
    logFile
  };
}
export {
  centerTruncatePath,
  convertHistoryToUIMessages,
  createErrorMessage,
  createQueuedUserMessage,
  createStreamingMessage,
  createSystemMessage,
  createToolMessage,
  createUserMessage,
  extractAutomationTriggerInfo,
  formatPathForDisplay,
  formatToolHeader,
  formatToolResultPreview,
  getStartupInfo,
  getToolDisplayName,
  getToolTypeBadge,
  makeRelativePath,
  normalizeToolName,
  shouldHideTool,
  stripAutomationTriggerTags
};
