/**
 * VectorDrive Store Tool
 *
 * Store a vector with metadata in the native VectorDb.
 */

import { Type } from "@sinclair/typebox";
import type { ExtensionAPI } from "@singularity-forge/pi-coding-agent";
import { VectordriveManager, textToVector } from "./manager.js";

export interface ToolExecutionResult {
	content: Array<{ type: "text"; text: string }>;
	details: Record<string, unknown>;
	isError?: boolean;
}

export function registerVectordriveStoreTool(pi: ExtensionAPI): void {
	pi.registerTool({
		name: "vectordrive_store",
		label: "VectorDrive Store",
		description:
			"Store a vector entry in VectorDrive. Accepts either a pre-computed " +
			"vector array or raw text (a simple hash embedding is generated automatically). " +
			"Metadata is stored as JSON and returned in search results.",
		promptSnippet: "Store a memory or code chunk in VectorDrive",
		parameters: Type.Object({
			id: Type.String({
				description: "Unique identifier for this entry (e.g. file-path:line-range)",
			}),
			text: Type.Optional(
				Type.String({
					description: "Raw text content to store. A simple embedding is auto-generated if 'vector' is not provided.",
				}),
			),
			vector: Type.Optional(
				Type.Array(Type.Number(), {
					description: "Pre-computed embedding vector (384 dimensions). Overrides 'text' if provided.",
				}),
			),
			metadata: Type.Optional(
				Type.Record(Type.String(), Type.Unknown(), {
					description: "Optional metadata object (e.g. { file_path, line_start, language })",
				}),
			),
		}),
		async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
			const manager = VectordriveManager.getInstance();
			const status = await manager.getStatus();

			if (status.backend === "none") {
				return {
					content: [
						{
							type: "text",
							text: `VectorDrive is unavailable: ${status.error ?? "unknown error"}\n\nInstall with: npm install vectordrive`,
						},
					],
					details: { status },
					isError: true,
				};
			}

			const id = params.id.trim();
			if (!id) {
				return {
					content: [{ type: "text", text: "Error: id is required." }],
					details: { error: "missing_id" },
					isError: true,
				};
			}

			let vector: number[];
			if (params.vector && params.vector.length > 0) {
				vector = params.vector;
			} else if (params.text) {
				vector = textToVector(params.text);
			} else {
				return {
					content: [
						{ type: "text", text: "Error: either 'text' or 'vector' must be provided." },
					],
					details: { error: "missing_content" },
					isError: true,
				};
			}

			const metadata: Record<string, unknown> = {
				...(params.metadata ?? {}),
				stored_at: new Date().toISOString(),
			};
			if (params.text) {
				metadata.text_preview = params.text.slice(0, 200);
			}

			const ok = await manager.store({ id, vector, metadata });
			if (!ok) {
				return {
					content: [{ type: "text", text: "Error: failed to store entry." }],
					details: { error: "store_failed" },
					isError: true,
				};
			}

			return {
				content: [
					{
						type: "text",
						text: `Stored ${id} (${vector.length} dims).`,
					},
				],
				details: { id, dimensions: vector.length, metadata },
				isError: false,
			};
		},
	});
}
