import { agents, subAgentTeamAgentRelations, subAgents } from "../../db/manage/manage-schema.js";
import { deriveRelationId } from "../../utils/conversations.js";
import { agentScopedWhere, subAgentScopedWhere } from "./scope-helpers.js";
import { and, count, desc, eq } from "drizzle-orm";

//#region src/data-access/manage/subAgentTeamAgentRelations.ts
const getSubAgentTeamAgentRelationById = (db) => async (params) => {
	return db.query.subAgentTeamAgentRelations.findFirst({ where: and(subAgentScopedWhere(subAgentTeamAgentRelations, params.scopes), eq(subAgentTeamAgentRelations.id, params.relationId)) });
};
const listSubAgentTeamAgentRelations = (db) => async (params) => {
	const page = params.pagination?.page || 1;
	const limit = Math.min(params.pagination?.limit || 10, 100);
	const offset = (page - 1) * limit;
	const whereClause = subAgentScopedWhere(subAgentTeamAgentRelations, params.scopes);
	const [data, totalResult] = await Promise.all([db.select().from(subAgentTeamAgentRelations).where(whereClause).limit(limit).offset(offset).orderBy(desc(subAgentTeamAgentRelations.createdAt)), db.select({ count: count() }).from(subAgentTeamAgentRelations).where(whereClause)]);
	const total = totalResult[0]?.count || 0;
	return {
		data,
		pagination: {
			page,
			limit,
			total,
			pages: Math.ceil(total / limit)
		}
	};
};
const getSubAgentTeamAgentRelations = (db) => async (params) => {
	return await db.query.subAgentTeamAgentRelations.findMany({ where: subAgentScopedWhere(subAgentTeamAgentRelations, params.scopes) });
};
const getSubAgentTeamAgentRelationsByAgent = (db) => async (params) => {
	return await db.query.subAgentTeamAgentRelations.findMany({ where: agentScopedWhere(subAgentTeamAgentRelations, params.scopes) });
};
const getSubAgentTeamAgentRelationsByTeamAgent = (db) => async (params) => {
	const page = params.pagination?.page || 1;
	const limit = Math.min(params.pagination?.limit || 10, 100);
	const offset = (page - 1) * limit;
	const whereClause = and(agentScopedWhere(subAgentTeamAgentRelations, params.scopes), eq(subAgentTeamAgentRelations.targetAgentId, params.targetAgentId));
	const [data, totalResult] = await Promise.all([db.select().from(subAgentTeamAgentRelations).where(whereClause).limit(limit).offset(offset).orderBy(desc(subAgentTeamAgentRelations.createdAt)), db.select({ count: count() }).from(subAgentTeamAgentRelations).where(whereClause)]);
	const total = totalResult[0]?.count || 0;
	return {
		data,
		pagination: {
			page,
			limit,
			total,
			pages: Math.ceil(total / limit)
		}
	};
};
const getTeamAgentsForSubAgent = (db) => async (params) => {
	const page = params.pagination?.page || 1;
	const limit = Math.min(params.pagination?.limit || 10, 100);
	const offset = (page - 1) * limit;
	const whereClause = subAgentScopedWhere(subAgentTeamAgentRelations, params.scopes);
	const [data, totalResult] = await Promise.all([db.select({
		id: subAgentTeamAgentRelations.id,
		tenantId: subAgentTeamAgentRelations.tenantId,
		projectId: subAgentTeamAgentRelations.projectId,
		agentId: subAgentTeamAgentRelations.agentId,
		subAgentId: subAgentTeamAgentRelations.subAgentId,
		targetAgentId: subAgentTeamAgentRelations.targetAgentId,
		headers: subAgentTeamAgentRelations.headers,
		createdAt: subAgentTeamAgentRelations.createdAt,
		updatedAt: subAgentTeamAgentRelations.updatedAt,
		targetAgent: {
			id: agents.id,
			name: agents.name,
			description: agents.description,
			defaultSubAgentId: agents.defaultSubAgentId,
			contextConfigId: agents.contextConfigId,
			models: agents.models,
			statusUpdates: agents.statusUpdates,
			prompt: agents.prompt,
			stopWhen: agents.stopWhen,
			createdAt: agents.createdAt,
			updatedAt: agents.updatedAt
		}
	}).from(subAgentTeamAgentRelations).innerJoin(agents, and(eq(subAgentTeamAgentRelations.tenantId, agents.tenantId), eq(subAgentTeamAgentRelations.projectId, agents.projectId), eq(subAgentTeamAgentRelations.targetAgentId, agents.id))).where(whereClause).limit(limit).offset(offset).orderBy(desc(subAgentTeamAgentRelations.createdAt)), db.select({ count: count() }).from(subAgentTeamAgentRelations).where(whereClause)]);
	const total = totalResult[0]?.count || 0;
	return {
		data,
		pagination: {
			page,
			limit,
			total,
			pages: Math.ceil(total / limit)
		}
	};
};
const getSubAgentsForTeamAgent = (db) => async (params) => {
	const page = params.pagination?.page || 1;
	const limit = Math.min(params.pagination?.limit || 10, 100);
	const offset = (page - 1) * limit;
	const whereClause = and(agentScopedWhere(subAgentTeamAgentRelations, params.scopes), eq(subAgentTeamAgentRelations.targetAgentId, params.targetAgentId));
	const [data, totalResult] = await Promise.all([db.select({
		id: subAgentTeamAgentRelations.id,
		tenantId: subAgentTeamAgentRelations.tenantId,
		projectId: subAgentTeamAgentRelations.projectId,
		agentId: subAgentTeamAgentRelations.agentId,
		subAgentId: subAgentTeamAgentRelations.subAgentId,
		targetAgentId: subAgentTeamAgentRelations.targetAgentId,
		createdAt: subAgentTeamAgentRelations.createdAt,
		updatedAt: subAgentTeamAgentRelations.updatedAt,
		subAgent: {
			id: subAgents.id,
			name: subAgents.name,
			description: subAgents.description,
			prompt: subAgents.prompt,
			conversationHistoryConfig: subAgents.conversationHistoryConfig,
			models: subAgents.models,
			stopWhen: subAgents.stopWhen,
			createdAt: subAgents.createdAt,
			updatedAt: subAgents.updatedAt
		}
	}).from(subAgentTeamAgentRelations).innerJoin(subAgents, and(eq(subAgentTeamAgentRelations.subAgentId, subAgents.id), eq(subAgentTeamAgentRelations.tenantId, subAgents.tenantId), eq(subAgentTeamAgentRelations.projectId, subAgents.projectId), eq(subAgentTeamAgentRelations.agentId, subAgents.agentId))).where(whereClause).limit(limit).offset(offset).orderBy(desc(subAgentTeamAgentRelations.createdAt)), db.select({ count: count() }).from(subAgentTeamAgentRelations).where(whereClause)]);
	const total = totalResult[0]?.count || 0;
	return {
		data,
		pagination: {
			page,
			limit,
			total,
			pages: Math.ceil(total / limit)
		}
	};
};
const createSubAgentTeamAgentRelation = (db) => async (params) => {
	const finalRelationId = params.relationId ?? deriveRelationId(params.scopes.tenantId, params.scopes.projectId, params.scopes.agentId, params.scopes.subAgentId, params.data.targetAgentId);
	return (await db.insert(subAgentTeamAgentRelations).values({
		id: finalRelationId,
		...params.scopes,
		targetAgentId: params.data.targetAgentId,
		headers: params.data.headers
	}).returning())[0];
};
/**
* Check if sub-agent team agent relation exists by params
*/
const getSubAgentTeamAgentRelationByParams = (db) => async (params) => {
	return db.query.subAgentTeamAgentRelations.findFirst({ where: and(subAgentScopedWhere(subAgentTeamAgentRelations, params.scopes), eq(subAgentTeamAgentRelations.targetAgentId, params.targetAgentId)) });
};
/**
* Upsert sub-agent team agent relation (create if it doesn't exist, update if it does)
*/
const upsertSubAgentTeamAgentRelation = (db) => async (params) => {
	if (params.relationId) return await updateSubAgentTeamAgentRelation(db)({
		scopes: params.scopes,
		relationId: params.relationId,
		data: params.data
	});
	const existing = await getSubAgentTeamAgentRelationByParams(db)({
		scopes: params.scopes,
		targetAgentId: params.data.targetAgentId
	});
	if (existing) return await updateSubAgentTeamAgentRelation(db)({
		scopes: params.scopes,
		relationId: existing.id,
		data: params.data
	});
	return await createSubAgentTeamAgentRelation(db)(params);
};
const updateSubAgentTeamAgentRelation = (db) => async (params) => {
	const updateData = {
		...params.data,
		updatedAt: (/* @__PURE__ */ new Date()).toISOString()
	};
	return (await db.update(subAgentTeamAgentRelations).set(updateData).where(and(subAgentScopedWhere(subAgentTeamAgentRelations, params.scopes), eq(subAgentTeamAgentRelations.id, params.relationId))).returning())[0];
};
const deleteSubAgentTeamAgentRelation = (db) => async (params) => {
	return (await db.delete(subAgentTeamAgentRelations).where(and(subAgentScopedWhere(subAgentTeamAgentRelations, params.scopes), eq(subAgentTeamAgentRelations.id, params.relationId))).returning()).length > 0;
};
const deleteSubAgentTeamAgentRelationsBySubAgent = (db) => async (params) => {
	return (await db.delete(subAgentTeamAgentRelations).where(subAgentScopedWhere(subAgentTeamAgentRelations, params.scopes)).returning()).length > 0;
};
const deleteSubAgentTeamAgentRelationsByAgent = (db) => async (params) => {
	return (await db.delete(subAgentTeamAgentRelations).where(agentScopedWhere(subAgentTeamAgentRelations, params.scopes)).returning()).length > 0;
};

//#endregion
export { createSubAgentTeamAgentRelation, deleteSubAgentTeamAgentRelation, deleteSubAgentTeamAgentRelationsByAgent, deleteSubAgentTeamAgentRelationsBySubAgent, getSubAgentTeamAgentRelationById, getSubAgentTeamAgentRelationByParams, getSubAgentTeamAgentRelations, getSubAgentTeamAgentRelationsByAgent, getSubAgentTeamAgentRelationsByTeamAgent, getSubAgentsForTeamAgent, getTeamAgentsForSubAgent, listSubAgentTeamAgentRelations, updateSubAgentTeamAgentRelation, upsertSubAgentTeamAgentRelation };