import { requireProjectPermission } from "../../../middleware/projectAccess.js";
import { openapiRegisterPutPatchRoutesForLegacy } from "../../../utils/openapiDualRoute.js";
import { speakeasyOffsetLimitPagination } from "../../../utils/speakeasy.js";
import { OpenAPIHono } from "@hono/zod-openapi";
import { ErrorResponseSchema, PaginationQueryParamsSchema, SubAgentRelationApiInsertSchema, SubAgentRelationApiUpdateSchema, SubAgentRelationListResponse, SubAgentRelationQuerySchema, SubAgentRelationResponse, TenantProjectAgentIdParamsSchema, TenantProjectAgentParamsSchema, commonGetErrorResponses, createApiError, createSubAgentRelation, deleteSubAgentRelation, deriveRelationId, getAgentRelationById, getAgentRelationsBySource, getSubAgentRelationsByTarget, listAgentRelations, updateAgentRelation, validateSubAgent } from "@inkeep/agents-core";
import { createProtectedRoute } from "@inkeep/agents-core/middleware";

//#region src/domains/manage/routes/subAgentRelations.ts
const app = new OpenAPIHono();
app.openapi(createProtectedRoute({
	method: "get",
	path: "/",
	summary: "List Sub Agent Relations",
	operationId: "list-sub-agent-relations",
	tags: ["SubAgents"],
	permission: requireProjectPermission("view"),
	request: {
		params: TenantProjectAgentParamsSchema,
		query: PaginationQueryParamsSchema.merge(SubAgentRelationQuerySchema)
	},
	responses: {
		200: {
			description: "List of sub agent relations retrieved successfully",
			content: { "application/json": { schema: SubAgentRelationListResponse } }
		},
		...commonGetErrorResponses
	},
	...speakeasyOffsetLimitPagination
}), async (c) => {
	const db = c.get("db");
	const { tenantId, projectId, agentId } = c.req.valid("param");
	const { page = 1, limit = 10, sourceSubAgentId, targetSubAgentId } = c.req.valid("query");
	const pageNum = Number(page);
	const limitNum = Math.min(Number(limit), 100);
	try {
		let result;
		if (sourceSubAgentId) {
			const rawResult = await getAgentRelationsBySource(db)({
				scopes: {
					tenantId,
					projectId,
					agentId
				},
				sourceSubAgentId,
				pagination: {
					page: pageNum,
					limit: limitNum
				}
			});
			result = {
				...rawResult,
				data: rawResult.data
			};
		} else if (targetSubAgentId) {
			const rawResult = await getSubAgentRelationsByTarget(db)({
				scopes: {
					tenantId,
					projectId,
					agentId
				},
				targetSubAgentId,
				pagination: {
					page: pageNum,
					limit: limitNum
				}
			});
			result = {
				...rawResult,
				data: rawResult.data
			};
		} else {
			const rawResult = await listAgentRelations(db)({
				scopes: {
					tenantId,
					projectId,
					agentId
				},
				pagination: {
					page: pageNum,
					limit: limitNum
				}
			});
			result = {
				...rawResult,
				data: rawResult.data
			};
		}
		return c.json(result);
	} catch {
		throw createApiError({
			code: "internal_server_error",
			message: "Failed to retrieve sub agent relations"
		});
	}
});
app.openapi(createProtectedRoute({
	method: "get",
	path: "/{id}",
	summary: "Get Sub Agent Relation",
	operationId: "get-sub-agent-relation-by-id",
	tags: ["SubAgents"],
	permission: requireProjectPermission("view"),
	request: { params: TenantProjectAgentIdParamsSchema },
	responses: {
		200: {
			description: "Sub Agent relation found",
			content: { "application/json": { schema: SubAgentRelationResponse } }
		},
		...commonGetErrorResponses
	}
}), async (c) => {
	const db = c.get("db");
	const { tenantId, projectId, agentId, id } = c.req.valid("param");
	const agentRelation = await getAgentRelationById(db)({
		scopes: {
			tenantId,
			projectId,
			agentId
		},
		relationId: id
	});
	if (!agentRelation) throw createApiError({
		code: "not_found",
		message: "Sub Agent Relation not found"
	});
	return c.json({ data: agentRelation });
});
app.openapi(createProtectedRoute({
	method: "post",
	path: "/",
	summary: "Create Sub Agent Relation",
	operationId: "create-sub-agent-relation",
	tags: ["SubAgents"],
	permission: requireProjectPermission("edit"),
	request: {
		params: TenantProjectAgentParamsSchema,
		body: { content: { "application/json": { schema: SubAgentRelationApiInsertSchema } } }
	},
	responses: {
		201: {
			description: "Sub Agent Relation created successfully",
			content: { "application/json": { schema: SubAgentRelationResponse } }
		},
		...commonGetErrorResponses
	}
}), async (c) => {
	const db = c.get("db");
	const { tenantId, projectId, agentId } = c.req.valid("param");
	const body = await c.req.valid("json");
	if (body.targetSubAgentId) {
		if (!await validateSubAgent(db)({ scopes: {
			tenantId,
			projectId,
			agentId,
			subAgentId: body.targetSubAgentId
		} })) throw createApiError({
			code: "bad_request",
			message: `Sub agent with ID ${body.targetSubAgentId} not found`
		});
	}
	if ((await listAgentRelations(db)({
		scopes: {
			tenantId,
			projectId,
			agentId
		},
		pagination: {
			page: 1,
			limit: 1e3
		}
	})).data.some((relation) => {
		if (relation.agentId !== agentId || relation.sourceSubAgentId !== body.sourceSubAgentId) return false;
		return relation.targetSubAgentId === body.targetSubAgentId;
	})) throw createApiError({
		code: "unprocessable_entity",
		message: `A relation between these agents in this agent already exists`
	});
	const relationData = {
		...body,
		agentId,
		tenantId,
		id: deriveRelationId(tenantId, projectId, agentId, body.sourceSubAgentId, body.targetSubAgentId ?? body.externalSubAgentId ?? body.teamSubAgentId ?? "", body.relationType ?? ""),
		projectId
	};
	const agentRelation = await createSubAgentRelation(db)({ ...relationData });
	return c.json({ data: agentRelation }, 201);
});
const updateSubAgentRelationRouteConfig = {
	path: "/{id}",
	summary: "Update Sub Agent Relation",
	tags: ["SubAgents"],
	permission: requireProjectPermission("edit"),
	request: {
		params: TenantProjectAgentIdParamsSchema,
		body: { content: { "application/json": { schema: SubAgentRelationApiUpdateSchema } } }
	},
	responses: {
		200: {
			description: "Sub Agent relation updated successfully",
			content: { "application/json": { schema: SubAgentRelationResponse } }
		},
		...commonGetErrorResponses
	}
};
const updateSubAgentRelationHandler = async (c) => {
	const db = c.get("db");
	const { tenantId, projectId, agentId, id } = c.req.valid("param");
	const body = await c.req.valid("json");
	const updatedAgentRelation = await updateAgentRelation(db)({
		scopes: {
			tenantId,
			projectId,
			agentId
		},
		relationId: id,
		data: body
	});
	if (!updatedAgentRelation) throw createApiError({
		code: "not_found",
		message: "Sub Agent Relation not found"
	});
	return c.json({ data: updatedAgentRelation });
};
openapiRegisterPutPatchRoutesForLegacy(app, updateSubAgentRelationRouteConfig, updateSubAgentRelationHandler, { operationId: "update-sub-agent-relation" });
app.openapi(createProtectedRoute({
	method: "delete",
	path: "/{id}",
	summary: "Delete Sub Agent Relation",
	operationId: "delete-sub-agent-relation",
	tags: ["SubAgents"],
	permission: requireProjectPermission("edit"),
	request: { params: TenantProjectAgentIdParamsSchema },
	responses: {
		204: { description: "Sub Agent Relation deleted successfully" },
		404: {
			description: "Sub Agent Relation not found",
			content: { "application/json": { schema: ErrorResponseSchema } }
		}
	}
}), async (c) => {
	const db = c.get("db");
	const { tenantId, projectId, agentId, id } = c.req.valid("param");
	if (!await deleteSubAgentRelation(db)({
		scopes: {
			tenantId,
			projectId,
			agentId
		},
		relationId: id
	})) throw createApiError({
		code: "not_found",
		message: "Sub Agent Relation not found"
	});
	return c.body(null, 204);
});
var subAgentRelations_default = app;

//#endregion
export { subAgentRelations_default as default };