import { MUTATION_TOOLS } from "./assistant-tools.js";
import type { PendingAssistantApproval } from "./assistant-approvals.js";

export const ASSISTANT_CONFIRMATION_PREFIX = "CONFIRMATION_REQUIRED:";

export type ChatMessage = { role: "user" | "assistant"; content: string };

export function parseToolArguments(args: string): Record<string, unknown> {
  try {
    const parsed = JSON.parse(args) as unknown;
    return parsed && typeof parsed === "object" && !Array.isArray(parsed)
      ? parsed as Record<string, unknown>
      : {};
  } catch {
    return {};
  }
}

export function formatApprovalValue(value: unknown): string {
  if (typeof value === "string") {
    return value.length > 48 ? `${value.slice(0, 45)}...` : value;
  }
  if (typeof value === "number" || typeof value === "boolean") {
    return String(value);
  }
  if (Array.isArray(value)) {
    if (value.length === 0) return "[]";
    return `[${value.slice(0, 3).map((item) => formatApprovalValue(item)).join(", ")}${value.length > 3 ? ", ..." : ""}]`;
  }
  if (value && typeof value === "object") {
    return "{...}";
  }
  return "null";
}

export function buildApprovalSummary(toolName: string, toolArguments: string): string {
  const params = parseToolArguments(toolArguments);
  const details = Object.entries(params)
    .filter(([, value]) => value !== undefined && value !== null && value !== "")
    .slice(0, 4)
    .map(([key, value]) => `${key}=${formatApprovalValue(value)}`)
    .join(", ");

  const action = toolName.replace(/_/g, " ");
  return details ? `${action} (${details})` : action;
}

export function isAffirmativeConfirmationReply(content: string): boolean {
  const normalized = content.trim().toLowerCase();
  if (!normalized) return false;

  const exactMatches = new Set([
    "ja",
    "yes",
    "y",
    "ok",
    "okay",
    "okey",
    "mach das",
    "bitte machen",
    "bitte ausführen",
    "bitte ausfuehren",
    "ausführen",
    "ausfuehren",
    "bestätigt",
    "bestaetigt",
    "bestätigen",
    "bestaetigen",
    "confirm",
    "confirmed",
    "do it",
    "go ahead",
    "proceed",
  ]);
  if (exactMatches.has(normalized)) return true;

  const affirmativePatterns = [
    /^(ja|yes|ok|okay)\b/,
    /\b(mach|make|do|führ|fuehr|execute|run)\b.*\b(das|it|bitte|jetzt)\b/,
    /\b(bit(?:te)?|please)\b.*\b(ausführen|ausfuehren|execute|run|machen|do)\b/,
    /\b(bestätig|bestaetig|confirm)\w*\b/,
    /\b(go ahead|proceed)\b/,
  ];
  return affirmativePatterns.some((pattern) => pattern.test(normalized));
}

export function isCancellationReply(content: string): boolean {
  const normalized = content.trim().toLowerCase();
  if (!normalized) return false;

  const exactMatches = new Set([
    "nein",
    "no",
    "abbrechen",
    "cancel",
    "stopp",
    "stop",
    "doch nicht",
    "nicht ausführen",
    "nicht ausfuehren",
  ]);
  if (exactMatches.has(normalized)) return true;

  return [
    /\b(nein|no|cancel|abbrechen|stop|stopp)\b/,
    /\b(doch nicht|nicht ausführen|nicht ausfuehren)\b/,
  ].some((pattern) => pattern.test(normalized));
}

export function hasPendingAssistantConfirmation(messages: ChatMessage[]): boolean {
  if (messages.length < 2) return false;
  const lastMessage = messages[messages.length - 1];
  if (!lastMessage || lastMessage.role !== "user") return false;

  for (let index = messages.length - 2; index >= 0; index -= 1) {
    const message = messages[index];
    if (!message) continue;
    if (message.role === "assistant") {
      return message.content.trimStart().startsWith(ASSISTANT_CONFIRMATION_PREFIX);
    }
  }

  return false;
}

export function canExecuteMutationTool(
  messages: ChatMessage[],
  toolName: string,
  pendingApproval?: PendingAssistantApproval | null,
): boolean {
  if (!MUTATION_TOOLS.has(toolName)) return true;
  const lastMessage = messages[messages.length - 1];
  if (!lastMessage || lastMessage.role !== "user") return false;
  if (!isAffirmativeConfirmationReply(lastMessage.content)) return false;

  if (pendingApproval) {
    return pendingApproval.toolName === toolName && pendingApproval.expiresAt > Date.now();
  }

  return hasPendingAssistantConfirmation(messages);
}
