import type { ToolCall, ToolResult } from '@/api/types';
import type { ToolRun } from '@/components/ToolCallLine';

export interface AcpWireMeta {
  status?: 'running' | 'completed' | 'failed' | 'canceled';
  kind?: string | null;
  title?: string;
  output?: unknown;
  error?: string;
}

export interface CoderToolCallWire {
  id: string;
  function: { name: string; arguments: string };
}

function parseArgs(raw: string): Record<string, unknown> {
  try {
    const parsed = JSON.parse(raw) as Record<string, unknown>;
    return parsed && typeof parsed === 'object' ? parsed : {};
  } catch {
    return {};
  }
}

export function wireToolCallToRun(wire: CoderToolCallWire): ToolRun {
  const args = parseArgs(wire.function.arguments);
  const acp = args._acp as AcpWireMeta | undefined;
  const { _acp: _ignored, ...rest } = args;
  const lifecycle = acp?.status ?? 'running';
  const call: ToolCall = {
    id: wire.id,
    name: wire.function.name,
    args: rest,
  };
  if (lifecycle === 'running') {
    return { call, result: null };
  }
  const result: ToolResult = {
    tool_call_id: wire.id,
    output: acp?.output ?? null,
    truncated: false,
    ...(acp?.error ? { error: acp.error } : {}),
  };
  return { call, result };
}

export function mergeWireToolCall(
  existing: CoderToolCallWire[] | undefined,
  incoming: { id: string; name: string; args: Record<string, unknown> },
): CoderToolCallWire[] {
  const entry: CoderToolCallWire = {
    id: incoming.id,
    function: { name: incoming.name, arguments: JSON.stringify(incoming.args) },
  };
  const list = existing ?? [];
  const idx = list.findIndex((tc) => tc.id === incoming.id);
  if (idx >= 0) {
    const next = [...list];
    next[idx] = entry;
    return next;
  }
  return [...list, entry];
}

