import { stableDigest, stableJsonStringify } from "@best-agent/foundation";
import type { ThreadEvidenceRecord, ToolInputValue } from "@best-agent/protocol";
import type { CustomLoopReplayState } from "../agent-runtime-tool-execution-types.js";
import { semanticToolInputDigest } from "../provider-turn/provider-tool-repeat-guard.js";

export function takeCustomLoopToolReplayResult(
  state: CustomLoopReplayState,
  toolName: string,
  toolInput: ToolInputValue,
): string | undefined {
  const toolInputKey = stableToolInputKey(toolInput);
  const inputDigest = rawToolInputDigest(toolInput);
  const inputStableDigest = semanticToolInputDigest(toolInput);
  const matchIndex = state.toolResults.findIndex(
    (result) =>
      result.toolName === toolName &&
      (result.toolInputStableDigest === inputStableDigest ||
        result.toolInputKey === toolInputKey ||
        result.toolInputDigest === inputDigest),
  );
  if (matchIndex < 0) {
    return undefined;
  }
  const [match] = state.toolResults.splice(matchIndex, 1);
  return match?.output;
}

export function customLoopEvidenceReplayKey(record: ThreadEvidenceRecord): string {
  return stableJsonStringify({
    confidence: record.confidence,
    kind: record.kind,
    payload: record.payload,
    relatedFilePaths: [...(record.relatedFilePaths ?? [])].sort(),
    sourceItemId: record.sourceItemId,
    summary: record.summary,
    threadId: record.threadId,
    turnId: record.turnId,
  });
}

export function stableToolInputKey(value: ToolInputValue): string {
  return stableJsonStringify(value);
}

export function isSameToolInputValue(left: ToolInputValue, right: ToolInputValue): boolean {
  return stableToolInputKey(left) === stableToolInputKey(right);
}

export function rawToolInputDigest(value: ToolInputValue): string {
  return stableDigest(value);
}
