import { externalAgents } from "../../db/manage/manage-schema.js";
import { projectScopedWhere } from "./scope-helpers.js";
import { and, asc, count, desc, eq } from "drizzle-orm";

//#region src/data-access/manage/externalAgents.ts
/**
* Create a new external agent
*/
const createExternalAgent = (db) => async (params) => {
	return (await db.insert(externalAgents).values(params).returning())[0];
};
/**
* Get external agent by ID
*/
const getExternalAgent = (db) => async (params) => {
	return await db.query.externalAgents.findFirst({ where: and(projectScopedWhere(externalAgents, params.scopes), eq(externalAgents.id, params.externalAgentId)) }) || null;
};
/**
* Get external agent by base URL
*/
const getExternalAgentByUrl = (db) => async (params) => {
	return await db.query.externalAgents.findFirst({ where: and(projectScopedWhere(externalAgents, params.scopes), eq(externalAgents.baseUrl, params.baseUrl)) }) || null;
};
/**
* List external agents for a project
*/
const listExternalAgents = (db) => async (params) => {
	return await db.query.externalAgents.findMany({
		where: projectScopedWhere(externalAgents, params.scopes),
		orderBy: [asc(externalAgents.name)]
	});
};
/**
* List external agents with pagination
*/
const listExternalAgentsPaginated = (db) => async (params) => {
	const page = params.pagination?.page || 1;
	const limit = Math.min(params.pagination?.limit || 10, 100);
	const offset = (page - 1) * limit;
	const [data, totalResult] = await Promise.all([db.select().from(externalAgents).where(projectScopedWhere(externalAgents, params.scopes)).limit(limit).offset(offset).orderBy(desc(externalAgents.createdAt)), db.select({ count: count() }).from(externalAgents).where(projectScopedWhere(externalAgents, params.scopes))]);
	const total = typeof totalResult[0]?.count === "string" ? parseInt(totalResult[0].count, 10) : totalResult[0]?.count || 0;
	return {
		data,
		pagination: {
			page,
			limit,
			total,
			pages: Math.ceil(total / limit)
		}
	};
};
/**
* Update an existing external agent
*/
const updateExternalAgent = (db) => async (params) => {
	const updateData = {
		...params.data,
		updatedAt: (/* @__PURE__ */ new Date()).toISOString()
	};
	if (Object.keys(updateData).length === 1) throw new Error("No fields to update");
	if (updateData.credentialReferenceId === void 0) updateData.credentialReferenceId = null;
	return (await db.update(externalAgents).set(updateData).where(and(projectScopedWhere(externalAgents, params.scopes), eq(externalAgents.id, params.externalAgentId))).returning())[0] || null;
};
/**
* Upsert external agent (create if it doesn't exist, update if it does)
*/
const upsertExternalAgent = (db) => async (params) => {
	const scopes = {
		tenantId: params.data.tenantId,
		projectId: params.data.projectId
	};
	if (await getExternalAgent(db)({
		scopes,
		externalAgentId: params.data.id
	})) {
		const updated = await updateExternalAgent(db)({
			scopes,
			externalAgentId: params.data.id,
			data: {
				name: params.data.name,
				description: params.data.description,
				baseUrl: params.data.baseUrl,
				credentialReferenceId: params.data.credentialReferenceId
			}
		});
		if (!updated) throw new Error("Failed to update external agent - no rows affected");
		return updated;
	}
	return await createExternalAgent(db)(params.data);
};
/**
* Delete an external agent
*/
const deleteExternalAgent = (db) => async (params) => {
	try {
		return (await db.delete(externalAgents).where(and(projectScopedWhere(externalAgents, params.scopes), eq(externalAgents.id, params.externalAgentId))).returning()).length > 0;
	} catch (error) {
		console.error("Error deleting external agent:", error);
		return false;
	}
};
/**
* Check if an external agent exists
*/
const externalAgentExists = (db) => async (params) => {
	return await getExternalAgent(db)(params) !== null;
};
/**
* Check if an external agent exists by URL
*/
const externalAgentUrlExists = (db) => async (params) => {
	return await getExternalAgentByUrl(db)(params) !== null;
};
/**
* Count external agents for a project
*/
const countExternalAgents = (db) => async (params) => {
	const countValue = (await db.select({ count: count() }).from(externalAgents).where(projectScopedWhere(externalAgents, params.scopes)))[0]?.count;
	return typeof countValue === "string" ? parseInt(countValue, 10) : countValue || 0;
};

//#endregion
export { countExternalAgents, createExternalAgent, deleteExternalAgent, externalAgentExists, externalAgentUrlExists, getExternalAgent, getExternalAgentByUrl, listExternalAgents, listExternalAgentsPaginated, updateExternalAgent, upsertExternalAgent };