const EXA_TOOL_ALIASES: Record<string, string> = {
	web_search_exa: "exa_web_search",
	web_fetch_exa: "exa_web_fetch",
	web_search_advanced_exa: "exa_web_search_advanced",
};

export type ExaToolDefinition = {
	name: string;
	label: string;
	[key: string]: unknown;
};

export function mapExaToolName(name: string): string {
	return EXA_TOOL_ALIASES[name] ?? name;
}

export function prefixExaTool<T extends ExaToolDefinition>(definition: T): T {
	const name = mapExaToolName(definition.name);
	if (name === definition.name) return definition;

	const displayName = name
		.slice("exa_".length)
		.split("_")
		.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
		.join(" ");
	return {
		...definition,
		name,
		label: `Exa ${displayName}`,
	} as T;
}

type ToolApi = {
	registerTool: (tool: unknown) => unknown;
	setActiveTools: (names: string[]) => unknown;
	unregisterTool?: (name: string) => boolean;
};

export function createExaToolApiOverride<T extends object>(pi: T): T {
	const api = pi as T & ToolApi;
	return new Proxy(pi, {
		get(target, property) {
			if (property === "registerTool") {
				return (definition: ExaToolDefinition) => api.registerTool(prefixExaTool(definition));
			}
			if (property === "setActiveTools") {
				return (names: string[]) => api.setActiveTools([...new Set(names.map(mapExaToolName))]);
			}
			if (property === "unregisterTool") {
				return api.unregisterTool ? (name: string) => api.unregisterTool?.(mapExaToolName(name)) : undefined;
			}

			const value = Reflect.get(target, property, target);
			return typeof value === "function" ? value.bind(target) : value;
		},
	}) as T;
}
