import type { OllamaToolDefinition } from "@/lib/ollama";
import { ALL_TOOL_DEFINITIONS } from "./definitions";
import { searchWeb } from "./search-web";
import { readPage } from "./read-page";
import { generatePdf } from "./generate-pdf";
import type { ToolContext, ToolHandler, ToolResult } from "./types";

export { TOOL_SYSTEM_PROMPT, ALL_TOOL_NAMES, TOOL_LABELS } from "./definitions";
export type { ToolContext, ToolResult } from "./types";

const HANDLERS: Record<string, ToolHandler> = {
  rechercher_web: searchWeb,
  lire_page: readPage,
  creer_pdf: generatePdf,
};

export function getToolDefinitions(enabledNames: string[]): OllamaToolDefinition[] {
  return enabledNames
    .map((n) => ALL_TOOL_DEFINITIONS[n])
    .filter((d): d is OllamaToolDefinition => !!d);
}

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

export async function runTool(
  name: string,
  rawArgs: unknown,
  ctx: ToolContext,
): Promise<ToolResult> {
  const handler = HANDLERS[name];
  if (!handler) {
    return { content: `Outil inconnu : ${name}`, error: "unknown_tool" };
  }
  const args = normalizeArgs(rawArgs);
  try {
    return await handler(args, ctx);
  } catch (e) {
    return {
      content: `Erreur dans ${name} : ${e instanceof Error ? e.message : "inconnue"}`,
      error: "exec_error",
    };
  }
}
