export interface TraceEventRow {
  rowId: string;
  seq: number | null;
  tone: "ok" | "blocked" | "warn" | "source";
  header: string;
  body: string | null;
  preview?: string | null;
  terminal?: boolean;
  bodyFormat?: "markdown" | "text";
}

type TraceEvent = Record<string, unknown>;
type TraceClockFormatter = (value: string) => string;

export interface TraceDisplayRowsOptions {
  formatClock?: TraceClockFormatter;
}

export function traceDisplayRows(trace: Record<string, unknown> = {}, events: TraceEvent[] = [], options: TraceDisplayRowsOptions = {}): TraceEventRow[] {
  const orderedEvents = traceEventsForDisplay(events);
  const effectiveTrace = traceWithInferredStart(trace, orderedEvents);
  const rows: TraceEventRow[] = [];
  const renderedSourceEvents = new Set<string>();
  const renderedToolIdentities = new Set<string>();
  for (let index = 0; index < orderedEvents.length; index += 1) {
    const event = orderedEvents[index];
    const sourceEventKey = traceSourceEventKey(event);
    if (sourceEventKey) {
      if (renderedSourceEvents.has(sourceEventKey)) continue;
      renderedSourceEvents.add(sourceEventKey);
    }
    if (!event || isNoisyTraceEvent(event)) continue;
    if (isToolTraceEvent(event)) {
      if (isSupersededToolStart(event, orderedEvents, index)) continue;
      const identity = toolIdentity(event);
      if (identity) {
        if (renderedToolIdentities.has(identity)) continue;
        renderedToolIdentities.add(identity);
      }
      rows.push(traceToolCallRow(effectiveTrace, event, options));
      continue;
    }
    if (isRequestTraceEvent(event)) {
      continue;
    }
    if (isSetupTraceEvent(event)) {
      continue;
    }
    if (isTerminalAssistantTraceEvent(event)) {
      rows.push(traceAssistantMessageRow(effectiveTrace, event, { terminal: true }, options));
      continue;
    }
    if (isAssistantTraceEvent(event)) {
      rows.push(traceAssistantMessageRow(effectiveTrace, event, { terminal: false }, options));
      continue;
    }
    if (isCompletionTraceEvent(event)) {
      const finalResponseText = traceFinalResponseText(effectiveTrace);
      rows.push(finalResponseText ? traceFinalResponseRow(event, finalResponseText, options) : traceCompletionSummaryRow(effectiveTrace, event, options));
      continue;
    }
    rows.push(traceDisplayRow(effectiveTrace, event, options));
  }
  const progressRow = traceBackendProgressSummaryRow(effectiveTrace, rows, orderedEvents, options);
  if (progressRow) rows.push(progressRow);
  if (rows.length > 0) return rows;
  if (orderedEvents.length === 0) return [];
  return orderedEvents.filter((event) => !isSuppressedTraceEvent(event)).map((event) => traceDisplayRow(effectiveTrace, event, options));
}

export function renderTraceRowsMarkdown(rows: TraceEventRow[] = []): string {
  if (!Array.isArray(rows) || rows.length === 0) return `_No rendered trace rows were returned._`;
  return rows.map((row, index) => renderTraceRowMarkdown(row, index + 1)).join("\n\n");
}

export function renderTraceRowMarkdown(row: TraceEventRow, index = 1): string {
  if (!isToolTraceRow(row)) return renderTraceMessageRowMarkdown(row);
  const body = renderTraceToolDetailBody(row) || row.header || `trace row ${index}`;
  return [
    `- <details>`,
    `  <summary>${escapeHtml(`已运行 ${traceToolSummary(row)}`)}</summary>`,
    ``,
    indentTraceMarkdownBlock(traceMarkdownFence(row.bodyFormat === "markdown" ? "markdown" : "text", body)),
    ``,
    `  </details>`
  ].join("\n");
}

function renderTraceMessageRowMarkdown(row: TraceEventRow): string {
  const body = row.body?.trimEnd();
  if (body) return traceBoldMarkdown(body);
  return traceBoldMarkdown(row.header || `_No readable trace row body._`);
}

function traceEventsForDisplay(events: TraceEvent[] = []): TraceEvent[] {
  return [...events].sort((left, right) => {
    const leftSeq = traceEventDisplaySeq(left);
    const rightSeq = traceEventDisplaySeq(right);
    if (leftSeq !== null || rightSeq !== null) {
      if (leftSeq === null) return 1;
      if (rightSeq === null) return -1;
      if (leftSeq !== rightSeq) return leftSeq - rightSeq;
    }
    const leftTime = traceEventTimestampMs(left);
    const rightTime = traceEventTimestampMs(right);
    if (leftTime !== null || rightTime !== null) {
      if (leftTime === null) return 1;
      if (rightTime === null) return -1;
      if (leftTime !== rightTime) return leftTime - rightTime;
    }
    return 0;
  });
}

function traceEventDisplaySeq(event: TraceEvent | null | undefined): number | null {
  return numberOrNull(event?.projectedSeq) ?? numberOrNull(event?.seq);
}

function traceEventIdentityToken(event: TraceEvent): string | number | null {
  const seq = traceEventDisplaySeq(event);
  return seq ?? nonEmptyString(event.projectedSeq ?? event.seq);
}

function isToolTraceRow(row: TraceEventRow): boolean {
  return row.rowId.startsWith("tool:") || /commandExecution/u.test(row.header);
}

function traceToolSummary(row: TraceEventRow): string {
  if (row.preview) return compactTraceOneLine(row.preview, 90);
  const firstLine = traceMarkdownPreviewLines(row.body).find((line) => !/^(stdout|stderr|exitCode|rowId|terminal):/iu.test(line.trim()));
  return compactTraceOneLine(stripTraceToolOutputFromSummary(firstLine || row.header || "tool call"), 90);
}

function stripTraceToolOutputFromSummary(value: string): string {
  return value.replace(/\s+(stdout:|stderr:|exitCode=).*$/isu, "").trim();
}

function traceToolCallRow(trace: Record<string, unknown>, event: TraceEvent, options: TraceDisplayRowsOptions): TraceEventRow {
  const command = cleanShellCommand(event.command);
  const status = traceStatusToken(event);
  const toolName = traceToolName(event, command);
  const body = traceToolCallBody(event, command);
  const eventKey = traceEventIdentityToken(event);
  return {
    rowId: `tool:${event.itemId ?? eventKey ?? `${event.label ?? event.type ?? "tool"}:${event.createdAt ?? "unknown"}`}`,
    seq: traceEventDisplaySeq(event),
    tone: traceEventTone(event),
    header: `${traceEventClock(event, options)} total=${formatTraceDuration(traceRelativeMs(trace, event))} ${status} ${toolName}`.trim(),
    body,
    preview: command ? compactTraceOneLine(command, 2000) : null,
    bodyFormat: "text"
  };
}

function traceToolName(event: TraceEvent, command: string | null): string {
  const direct = nonEmptyString(event.toolName);
  if (direct && !isProtocolToolLifecycleName(direct)) return direct;
  const label = readableTraceLabel(event).replace(/^agentrun:tool:/u, "").replace(/^tool:/u, "").replace(/^item\//u, "");
  if (label && !isProtocolToolLifecycleName(label)) return label;
  const commandName = traceToolNameFromCommand(command);
  if (commandName) return commandName;
  const previewName = traceToolNameFromPreview(event);
  if (previewName) return previewName;
  return "tool call";
}

function isProtocolToolLifecycleName(value: unknown): boolean {
  return /^(?:item\/)?(?:started|completed)$/iu.test(String(value ?? "").trim()) || /^item\/(?:started|completed)$/iu.test(String(value ?? "").trim());
}

function traceToolNameFromCommand(command: string | null): string | null {
  const text = cleanTraceText(command);
  const match = text.match(/^([A-Za-z][A-Za-z0-9_.:-]{1,80})(?:\s|$)/u);
  return match?.[1] ?? null;
}

function traceToolNameFromPreview(event: TraceEvent): string | null {
  const preview = traceEventText(event, ["output", "outputText", "outputSummary", "stdoutSummary", "message"]);
  return jsonPreviewStringField(preview, "toolName") ?? jsonPreviewStringField(preview, "type") ?? jsonPreviewStringField(preview, "name");
}

function jsonPreviewStringField(text: string | null, key: string): string | null {
  const body = String(text ?? "");
  if (!body || !/^[A-Za-z][A-Za-z0-9_]*$/u.test(key)) return null;
  const match = body.match(new RegExp(`"${key}"\\s*:\\s*"((?:\\\\.|[^"\\\\])*)"`, "u"));
  if (!match) return null;
  try {
    const parsed = JSON.parse(`"${match[1]}"`);
    return typeof parsed === "string" && parsed.trim() ? parsed.trim() : null;
  } catch {
    return match[1]?.trim() || null;
  }
}

function traceToolCallBody(event: TraceEvent, command: string | null): string | null {
  const lines = [
    command,
    traceDetailBlock("stdout", traceEventText(event, ["stdout", "stdoutText", "stdoutSummary"])),
    traceDetailBlock("stderr", traceEventText(event, ["stderr", "stderrText", "stderrSummary"])),
    command ? null : traceEventText(event, ["output", "outputText", "outputSummary"]),
    event.exitCode !== undefined ? `exitCode=${event.exitCode}` : null
  ].map(cleanTraceDetailText).filter(Boolean);
  return lines.length > 0 ? lines.join("\n") : null;
}

export function traceNoiseEventCount(events: TraceEvent[] = []): number {
  return Array.isArray(events) ? events.filter((event) => isNoisyTraceEvent(event)).length : 0;
}

function traceAssistantMessageRow(trace: Record<string, unknown>, event: TraceEvent, { terminal }: { terminal: boolean }, options: TraceDisplayRowsOptions): TraceEventRow {
  const text = cleanTraceDetailText(event.message ?? event.outputSummary ?? assistantStreamText(trace, event) ?? "");
  const index = Number.isInteger(event.messageIndex) ? Number(event.messageIndex) : null;
  const count = Number.isInteger(event.messageCount) ? Number(event.messageCount) : null;
  const eventKey = traceEventIdentityToken(event);
  return {
    rowId: `event:${eventKey ?? `${event.label ?? event.type ?? "assistant"}:${event.createdAt ?? "unknown"}`}`,
    seq: traceEventDisplaySeq(event),
    tone: "ok",
    header: `${traceEventClock(event, options)}  ${terminal ? "助手最终消息" : "助手消息"}${index ? ` ${index}${count ? `/${count}` : ""}` : ""}`,
    terminal: terminal ? true : undefined,
    body: text || null,
    bodyFormat: "markdown"
  };
}

function traceFinalResponseRow(event: TraceEvent, finalText: string, options: TraceDisplayRowsOptions): TraceEventRow {
  const eventKey = traceEventIdentityToken(event);
  return {
    rowId: `trace-final-response:${eventKey ?? "completed"}`,
    seq: traceEventDisplaySeq(event),
    tone: "ok",
    header: `${traceEventClock(event, options)}  助手最终消息`,
    terminal: true,
    body: finalText,
    bodyFormat: "markdown"
  };
}

function traceFinalResponseText(trace: Record<string, unknown>): string | null {
  const response = trace.finalResponse && typeof trace.finalResponse === "object" ? trace.finalResponse as Record<string, unknown> : null;
  return nonEmptyString(response?.text ?? response?.content ?? response?.message);
}

function traceCompletionSummaryRow(trace: Record<string, unknown>, event: TraceEvent, options: TraceDisplayRowsOptions): TraceEventRow {
  const eventKey = traceEventIdentityToken(event);
  return {
    rowId: `trace-completion:${eventKey ?? "turn"}`,
    seq: traceEventDisplaySeq(event),
    tone: traceEventTone(event),
    header: `${traceEventClock(event, options)}  轮次完成（总耗时 ${formatTraceDuration(traceRelativeMs(trace, event))}）`,
    body: null
  };
}

function traceNoiseSummaryRow(trace: Record<string, unknown>, events: TraceEvent[], options: TraceDisplayRowsOptions): TraceEventRow {
  const lastEvent = events.at(-1);
  const status = nonEmptyString(trace.status ?? trace.traceStatus) ?? "running";
  const lastLabel = lastEvent ? readableTraceLabel(lastEvent) : "未观测";
  return {
    rowId: "trace-noise-summary",
    seq: traceEventDisplaySeq(lastEvent),
    tone: lastEvent ? traceEventTone(lastEvent) : "source",
    header: `${traceEventClock(lastEvent, options)}  Trace ${status}，等待可读事件`,
    body: `已隐藏 ${events.length} 条 AgentRun backend 状态事件。最新原始事件：${lastLabel}。`,
    bodyFormat: "text"
  };
}

function traceBackendProgressSummaryRow(trace: Record<string, unknown>, rows: TraceEventRow[], events: TraceEvent[], options: TraceDisplayRowsOptions): TraceEventRow | null {
  if (!Array.isArray(events) || events.length === 0) return null;
  if (rows.some((row) => row.rowId.startsWith("tool:") || /助手|轮次完成/u.test(row.header))) return null;
  const lastRenderedSeq = Math.max(0, ...rows.map((row) => row.seq ?? 0).filter(Number.isFinite));
  const hiddenProgress = events.filter((event) => {
    const seq = traceEventDisplaySeq(event) ?? 0;
    return seq > lastRenderedSeq && (isRequestTraceEvent(event) || isSetupTraceEvent(event) || isNoisyTraceEvent(event));
  });
  return hiddenProgress.length > 0 ? traceNoiseSummaryRow(trace, hiddenProgress, options) : null;
}

function traceDisplayRow(trace: Record<string, unknown>, event: TraceEvent, options: TraceDisplayRowsOptions): TraceEventRow {
  const label = readableTraceLabel(event);
  const eventKey = traceEventIdentityToken(event);
  return {
    rowId: `event:${eventKey ?? `${event.label ?? event.type ?? "event"}:${event.createdAt ?? "unknown"}`}`,
    seq: traceEventDisplaySeq(event),
    tone: traceEventTone(event),
    header: `${traceEventClock(event, options)} total=${formatTraceDuration(traceRelativeMs(trace, event))} ${traceStatusToken(event)} ${label}`.trim(),
    body: traceDisplayBody(event)
  };
}

function assistantStreamText(trace: Record<string, unknown>, event: TraceEvent): string {
  const streams = Array.isArray(trace.assistantStreams) ? trace.assistantStreams.filter(isRecord) : [];
  const itemId = nonEmptyString(event.itemId ?? event.messageId ?? event.id);
  const matched = itemId ? streams.find((stream) => [stream.itemId, stream.messageId, stream.id].map(nonEmptyString).includes(itemId)) : null;
  return nonEmptyString(matched?.text ?? streams.at(-1)?.text) ?? "";
}

function isRequestTraceEvent(event: TraceEvent): boolean {
  const label = String(event.label ?? "");
  return label === "agentrun:request:accepted" || label === "request:accepted-short-connection" || label === "request:accepted" || label === "request:received";
}

function isSetupTraceEvent(event: TraceEvent): boolean {
  const label = String(event.label ?? "");
  return /^session:|^stdio:|^prompt:|^thread:|^turn:started|^turn:start|turn\/start|codex turn|tool:codex-app-server/iu.test(label) ||
    /^agentrun:backend:(codex-app-server-starting|initialize:completed|thread\/start|thread\/resume|thread\/started|turn\/start|turn\/started)/iu.test(label) ||
    /^agentrun:run:(reuse-skipped|reused)$/iu.test(label) ||
    /^agentrun:command:created$/iu.test(label) ||
    /^agentrun:runner-job:(created|ensured|reused)$/iu.test(label) ||
    /^agentrun:session-storage-recover-warning$/iu.test(label);
}

function isCompletionTraceEvent(event: TraceEvent): boolean {
  const label = String(event.label ?? "");
  return label.startsWith("turn:completed") || label.startsWith("result:completed") || label === "agentrun:backend:turn/completed" || label === "agentrun:terminal:completed" || label === "agentrun:result:completed";
}

function isAssistantTraceEvent(event: TraceEvent): boolean {
  const label = String(event.label ?? "");
  return label === "agentrun:assistant:message" || label === "assistant:message" || event.type === "assistant_message" || event.type === "assistant";
}

function isTerminalAssistantTraceEvent(event: TraceEvent): boolean {
  const label = String(event.label ?? "");
  if (label === "assistant:completed") return true;
  if (label === "agentrun:assistant:message") return event.replyAuthority === true || event.final === true;
  return event.type === "assistant_message" && (event.status === "completed" || event.final === true || event.terminal === true);
}

function isToolTraceEvent(event: TraceEvent): boolean {
  const label = String(event.label ?? "");
  const type = String(event.type ?? "");
  const toolName = String(event.toolName ?? "");
  return type === "tool_call" || toolName === "commandExecution" || /commandExecution|^agentrun:tool:/u.test(label);
}

function isToolStartTraceEvent(event: TraceEvent): boolean {
  const status = String(event.status ?? "").toLowerCase();
  const label = String(event.label ?? "");
  return ["started", "running", "inprogress", "in-progress"].includes(status) || /:started$|\/started$/u.test(label);
}

function isToolCompleteTraceEvent(event: TraceEvent): boolean {
  const status = String(event.status ?? "").toLowerCase();
  const label = String(event.label ?? "");
  return ["completed", "succeeded", "failed", "blocked", "timeout", "canceled", "cancelled"].includes(status) || /:completed$|\/completed$/u.test(label);
}

function toolIdentity(event: TraceEvent): string | null {
  return nonEmptyString(event.itemId ?? event.id ?? event.command);
}

function traceSourceEventKey(event: TraceEvent | null | undefined): string | null {
  if (!event || typeof event !== "object") return null;
  const source = nonEmptyString(event.source);
  const sourceSeq = nonEmptyString(event.sourceSeq);
  if (!source || !sourceSeq) return null;
  return `${source}:${sourceSeq}:${nonEmptyString(event.label ?? event.type) ?? "event"}`;
}

function isSupersededToolStart(event: TraceEvent, events: TraceEvent[], index: number): boolean {
  if (!isToolStartTraceEvent(event)) return false;
  const identity = toolIdentity(event);
  if (!identity) return false;
  return events.slice(index + 1).some((candidate) => candidate && isToolTraceEvent(candidate) && isToolCompleteTraceEvent(candidate) && toolIdentity(candidate) === identity);
}

function isNoisyTraceEvent(event: TraceEvent): boolean {
  const label = String(event.label ?? "");
  if (isRequestTraceEvent(event) || isSetupTraceEvent(event) || isCompletionTraceEvent(event) || isTerminalAssistantTraceEvent(event) || isAssistantTraceEvent(event)) return false;
  if (/^agentrun:backend:/u.test(label) && !event.errorCode) return true;
  if (/token_count|outputDelta:chunk/iu.test(label)) return true;
  if (/^agentrun:output:(stdout|stderr)$/u.test(label)) return true;
  if (/^agentrun:backend:(run-created|command-created|runner-job-created|thread\/status\/changed|thread\/tokenUsage\/updated|account\/rateLimits\/updated|remoteControl\/status\/changed|configWarning|codex-app-server-closed|codex-app-server-notifications-suppressed|session-updated|command-terminal|backend-turn-finished|item\/agentMessage:(started|completed)|thread\/goal\/cleared)$/u.test(label)) return true;
  return event.type === "event" && !event.outputSummary && !event.message && !event.errorCode;
}

function isSuppressedTraceEvent(event: TraceEvent): boolean {
  return isNoisyTraceEvent(event) || isRequestTraceEvent(event) || isSetupTraceEvent(event);
}

function readableTraceLabel(event: TraceEvent): string {
  const label = String(event.label ?? `${event.type ?? "event"}:${event.status ?? "observed"}`);
  if (label === "request:accepted-short-connection") return "submit short-connection";
  if (label === "request:accepted") return "request accepted";
  if (label.startsWith("turn:completed")) return "turn completed";
  if (label.startsWith("result:completed")) return "result ready";
  return label.replace(/^tool:/u, "").replace(/^assistant:/u, "assistant ").replace(/:completed$/u, " completed").replace(/:started$/u, " started");
}

function traceDisplayBody(event: TraceEvent): string | null {
  const command = cleanShellCommand(event.command);
  const lines = [
    command,
    traceDetailBlock("stdout", traceEventText(event, ["stdout", "stdoutText", "stdoutSummary"])),
    traceDetailBlock("stderr", traceEventText(event, ["stderr", "stderrText", "stderrSummary"])),
    traceEventText(event, ["output", "outputText", "outputSummary"]),
    traceEventText(event, ["prompt", "promptText", "promptSummary"]),
    traceEventText(event, ["message"]),
    traceEventText(event, ["chunk"])
  ].map(cleanTraceDetailText).filter(Boolean);
  return lines.length > 0 ? lines.join("\n") : null;
}

function traceMarkdownPreviewLines(body: string | null | undefined): string[] {
  return String(body ?? "")
    .replace(/\r\n|\r/gu, "\n")
    .trim()
    .split("\n")
    .map((line) => line.trimEnd())
    .filter((line) => Boolean(line.trim()));
}

function renderTraceRowDetailBody(row: TraceEventRow): string {
  return [
    row.body?.trimEnd() ?? "",
    row.rowId ? `rowId: ${row.rowId}` : "",
    row.terminal === true ? "terminal: true" : ""
  ].filter(Boolean).join("\n");
}

function renderTraceToolDetailBody(row: TraceEventRow): string {
  return normalizeTraceToolDetailBody(renderTraceRowDetailBody(row));
}

function normalizeTraceToolDetailBody(value: string): string {
  return String(value ?? "")
    .replace(/\r\n|\r/gu, "\n")
    .replace(/[^\S\n]+(stdout:)[^\S\n]*/giu, "\n$1\n")
    .replace(/[^\S\n]+(stderr:)[^\S\n]*/giu, "\n$1\n")
    .replace(/[^\S\n]+(exitCode=)/giu, "\n$1")
    .replace(/\n{3,}/gu, "\n\n")
    .trimEnd();
}

function traceBoldMarkdown(value: string): string {
  const body = String(value ?? "").trimEnd();
  if (!body) return "";
  return body.split("\n").map((line) => {
    if (!line.trim()) return "";
    return `**${escapeMarkdownStrongText(line)}**`;
  }).join("\n");
}

function escapeMarkdownStrongText(value: string): string {
  return escapeHtml(value).replace(/\\/gu, "\\\\").replace(/\*/gu, "\\*");
}

function indentTraceMarkdownBlock(value: string): string {
  return String(value).split("\n").map((line) => `  ${line}`).join("\n");
}

function escapeHtml(value: string): string {
  return String(value).replace(/&/gu, "&amp;").replace(/</gu, "&lt;").replace(/>/gu, "&gt;");
}

function traceMarkdownFence(language: string, body: string): string {
  const fence = body.includes("```") ? "````" : "```";
  return `${fence}${language}\n${body.trimEnd()}\n${fence}`;
}

function traceStatusToken(event: TraceEvent): string {
  const rawStatus = String(event.status ?? "");
  const status = rawStatus.toLowerCase();
  if (status === "completed" || status === "succeeded") return "ok";
  if (["failed", "blocked", "error", "timeout", "canceled"].includes(status) || event.errorCode) return "fail";
  if (["started", "running", "accepted", "inprogress", "in-progress"].includes(status)) return "run";
  return rawStatus || "event";
}

function traceEventTone(event: TraceEvent): TraceEventRow["tone"] {
  const status = traceStatusToken(event);
  if (status === "ok") return "ok";
  if (status === "fail") return "blocked";
  if (status === "run") return "warn";
  return "source";
}

function traceClock(value: unknown, options: TraceDisplayRowsOptions): string {
  const timestamp = nonEmptyString(value);
  if (timestamp && options.formatClock) return options.formatClock(timestamp);
  const date = new Date(String(value ?? ""));
  return Number.isNaN(date.getTime()) ? "--:--:--" : date.toISOString().slice(11, 19);
}

function traceEventClock(event: TraceEvent | null | undefined, options: TraceDisplayRowsOptions): string {
  return traceClock(traceEventTimestamp(event), options);
}

function traceWithInferredStart(trace: Record<string, unknown>, events: TraceEvent[]): Record<string, unknown> {
  if (nonEmptyString(trace.startedAt ?? trace.createdAt)) return trace;
  const firstTimestamp = events.map((event) => traceEventTimestamp(event)).find(Boolean);
  return firstTimestamp ? { ...trace, startedAt: firstTimestamp } : trace;
}

function traceEventTimestamp(event: TraceEvent | null | undefined): string | null {
  if (!event) return null;
  return nonEmptyString(event.createdAt ?? event.ts ?? event.timestamp ?? event.observedAt);
}

function traceEventTimestampMs(event: TraceEvent | null | undefined): number | null {
  const timestamp = traceEventTimestamp(event);
  if (!timestamp) return null;
  const parsed = Date.parse(timestamp);
  return Number.isFinite(parsed) ? parsed : null;
}

function traceRelativeMs(trace: Record<string, unknown>, event: TraceEvent): number {
  if (typeof event.elapsedMs === "number") return event.elapsedMs;
  const start = Date.parse(String(trace.startedAt ?? trace.createdAt ?? ""));
  const current = Date.parse(String(traceEventTimestamp(event) ?? ""));
  return Number.isNaN(start) || Number.isNaN(current) ? 0 : Math.max(0, current - start);
}

function formatTraceDuration(ms: number): string {
  const seconds = Math.floor(Math.max(0, Number(ms) || 0) / 1000);
  return [Math.floor(seconds / 3600), Math.floor((seconds % 3600) / 60), seconds % 60].map((part) => String(part).padStart(2, "0")).join(":");
}

function cleanTraceText(value: unknown): string {
  return String(value ?? "").replace(/\u0000/gu, "").replace(/\r\n|\r/gu, "\n").replace(/[ \t]{2,}/gu, " ").replace(/\n{3,}/gu, "\n\n").trim();
}

function cleanTraceDetailText(value: unknown): string {
  return String(value ?? "").replace(/\u0000/gu, "").replace(/\r\n|\r/gu, "\n").replace(/\n{4,}/gu, "\n\n\n").trim();
}

function traceEventText(event: TraceEvent, keys: string[]): string | null {
  for (const key of keys) {
    const value = event[key];
    if (value === undefined || value === null) continue;
    const body = cleanTraceDetailText(value);
    if (body) return body;
  }
  return null;
}

function traceDetailBlock(label: string, value: string | null): string | null {
  return value ? `${label}:\n${value}` : null;
}

function cleanShellCommand(value: unknown): string | null {
  const raw = cleanTraceDetailText(value);
  if (!raw) return null;
  const stripped = stripShellWrapper(raw);
  const unescaped = stripped.replace(/\\(["`$\\])/gu, "$1");
  return cleanTraceDetailText(unescaped);
}

function stripShellWrapper(value: string): string {
  const match = value.match(/^\s*(?:\/usr\/bin\/env\s+)?(?:\/bin\/sh|sh|bash|\/bin\/bash)\s+-lc\s+([\s\S]*)$/u);
  if (!match) return value;
  return unwrapShellArgument(match[1] ?? "");
}

function unwrapShellArgument(value: string): string {
  const text = value.trim();
  if (text.length >= 2) {
    const quote = text[0];
    if ((quote === "'" || quote === '"') && text[text.length - 1] === quote) {
      return text.slice(1, -1);
    }
  }
  return text;
}

function compactTraceOneLine(value: unknown, limit = 220): string {
  const text = cleanTraceText(value).replace(/\s+/gu, " ");
  return text.length <= limit ? text : `${text.slice(0, Math.max(0, limit - 3))}...`;
}

function numberOrNull(value: unknown): number | null {
  const number = Number(value);
  return Number.isInteger(number) ? number : null;
}

function nonEmptyString(value: unknown): string | null {
  const text = String(value ?? "").trim();
  return text ? text : null;
}

function isRecord(value: unknown): value is Record<string, unknown> {
  return Boolean(value && typeof value === "object");
}
