/**
 * Knowledge-base operations against a vector store using a given OpenAI client
 * (each tenant may use their own API key).
 */
import fs from "node:fs";
import path from "node:path";
import { toFile } from "openai";

export async function ingestStreams(client, vectorStoreId, files) {
  const openaiFiles = await Promise.all(
    files.map(async ({ name, stream }) => {
      const file = await toFile(stream, name);
      return client.files.create({ file, purpose: "assistants" });
    })
  );
  const batch = await client.vectorStores.fileBatches.createAndPoll(vectorStoreId, {
    file_ids: openaiFiles.map((f) => f.id),
  });
  return { batch, fileCount: openaiFiles.length };
}

export async function ingestText(client, vectorStoreId, filename, text) {
  return ingestStreams(client, vectorStoreId, [{ name: filename, stream: Buffer.from(text, "utf8") }]);
}

export async function ingestPaths(client, vectorStoreId, filePaths) {
  const files = filePaths.map((p) => ({ name: path.basename(p), stream: fs.createReadStream(p) }));
  return ingestStreams(client, vectorStoreId, files);
}

export async function listDocuments(client, vectorStoreId) {
  if (!vectorStoreId) return [];
  const out = [];
  const page = await client.vectorStores.files.list(vectorStoreId, { limit: 100 });
  for (const vf of page.data) {
    let filename = vf.id, bytes = null;
    try {
      const meta = await client.files.retrieve(vf.id);
      filename = meta.filename || vf.id;
      bytes = meta.bytes ?? null;
    } catch {}
    out.push({ id: vf.id, filename, status: vf.status, bytes });
  }
  return out;
}

export async function deleteDocument(client, vectorStoreId, fileId) {
  await client.vectorStores.files.del(vectorStoreId, fileId);
  try { await client.files.del(fileId); } catch {}
}
