import { getLogger as getLogger$1 } from "../../../../logger.js";
import runDbClient_default from "../../../../data/db/runDbClient.js";
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
import { DatasetRunApiSelectSchema, ListResponseSchema, SingleResponseSchema, TenantProjectParamsSchema, commonGetErrorResponses, createApiError, getConversation, getDatasetRunById, getDatasetRunConfigById, getDatasetRunConversationRelations, getMessagesByConversation, listDatasetItems, listDatasetRuns } from "@inkeep/agents-core";

//#region src/domains/manage/routes/evals/datasetRuns.ts
const app = new OpenAPIHono();
const logger = getLogger$1("datasetRuns");
app.openapi(createRoute({
	method: "get",
	path: "/by-dataset/{datasetId}",
	summary: "List Dataset Runs by Dataset ID",
	operationId: "list-dataset-runs",
	tags: ["Evaluations"],
	request: { params: TenantProjectParamsSchema.extend({ datasetId: z.string() }) },
	responses: {
		200: {
			description: "List of dataset runs",
			content: { "application/json": { schema: ListResponseSchema(DatasetRunApiSelectSchema) } }
		},
		...commonGetErrorResponses
	}
}), async (c) => {
	const db = c.get("db");
	const { tenantId, projectId, datasetId } = c.req.valid("param");
	try {
		const filteredRuns = (await listDatasetRuns(runDbClient_default)({ scopes: {
			tenantId,
			projectId
		} })).filter((run) => run.datasetId === datasetId);
		const runsWithNames = await Promise.all(filteredRuns.map(async (run) => {
			if (run.datasetRunConfigId) {
				const runConfig = await getDatasetRunConfigById(db)({ scopes: {
					tenantId,
					projectId,
					datasetRunConfigId: run.datasetRunConfigId
				} });
				return {
					...run,
					runConfigName: runConfig?.name || null
				};
			}
			return {
				...run,
				runConfigName: null
			};
		}));
		return c.json({
			data: runsWithNames,
			pagination: {
				page: 1,
				limit: runsWithNames.length,
				total: runsWithNames.length,
				pages: 1
			}
		});
	} catch (error) {
		logger.error({
			error,
			tenantId,
			projectId,
			datasetId
		}, "Failed to list dataset runs");
		return c.json(createApiError({
			code: "internal_server_error",
			message: "Failed to list dataset runs"
		}), 500);
	}
});
app.openapi(createRoute({
	method: "get",
	path: "/{runId}",
	summary: "Get Dataset Run by ID",
	operationId: "get-dataset-run",
	tags: ["Evaluations"],
	request: { params: TenantProjectParamsSchema.extend({ runId: z.string() }) },
	responses: {
		200: {
			description: "Dataset run with conversations",
			content: { "application/json": { schema: SingleResponseSchema(DatasetRunApiSelectSchema.extend({
				conversations: z.array(z.object({
					id: z.string(),
					conversationId: z.string(),
					datasetRunId: z.string(),
					agentId: z.string().nullable().optional(),
					output: z.string().nullable().optional(),
					createdAt: z.string(),
					updatedAt: z.string()
				})),
				items: z.array(z.object({
					id: z.string(),
					tenantId: z.string(),
					projectId: z.string(),
					datasetId: z.string(),
					input: z.any().nullable().optional(),
					expectedOutput: z.any().nullable().optional(),
					simulationAgent: z.any().nullable().optional(),
					createdAt: z.string(),
					updatedAt: z.string(),
					conversations: z.array(z.object({
						id: z.string(),
						conversationId: z.string(),
						datasetRunId: z.string(),
						agentId: z.string().nullable().optional(),
						output: z.string().nullable().optional(),
						createdAt: z.string(),
						updatedAt: z.string()
					}))
				}))
			})) } }
		},
		...commonGetErrorResponses
	}
}), async (c) => {
	const db = c.get("db");
	const { tenantId, projectId, runId } = c.req.valid("param");
	try {
		const run = await getDatasetRunById(runDbClient_default)({ scopes: {
			tenantId,
			projectId,
			datasetRunId: runId
		} });
		if (!run) return c.json(createApiError({
			code: "not_found",
			message: "Dataset run not found"
		}), 404);
		let runConfigName = null;
		if (run.datasetRunConfigId) runConfigName = (await getDatasetRunConfigById(db)({ scopes: {
			tenantId,
			projectId,
			datasetRunConfigId: run.datasetRunConfigId
		} }))?.name || null;
		const conversationRelations = await getDatasetRunConversationRelations(runDbClient_default)({ scopes: {
			tenantId,
			projectId,
			datasetRunId: runId
		} });
		const datasetItems = await listDatasetItems(db)({ scopes: {
			tenantId,
			projectId,
			datasetId: run.datasetId
		} });
		const itemsWithConversations = await Promise.all(datasetItems.map(async (item) => {
			const itemConversations = conversationRelations.filter((conv) => conv.datasetItemId === item.id);
			const conversationsWithOutput$1 = await Promise.all(itemConversations.map(async (conv) => {
				try {
					const agentId = (await getConversation(runDbClient_default)({
						scopes: {
							tenantId,
							projectId
						},
						conversationId: conv.conversationId
					}))?.agentId || null;
					const assistantMessage = (await getMessagesByConversation(runDbClient_default)({
						scopes: {
							tenantId,
							projectId
						},
						conversationId: conv.conversationId,
						pagination: {
							page: 1,
							limit: 100
						}
					})).filter((msg) => msg.role === "assistant" || msg.role === "agent").sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())[0];
					let output = null;
					if (assistantMessage?.content) {
						if (typeof assistantMessage.content === "string") output = assistantMessage.content;
						else if (typeof assistantMessage.content === "object" && assistantMessage.content !== null && "text" in assistantMessage.content) output = typeof assistantMessage.content.text === "string" ? assistantMessage.content.text : null;
					}
					return {
						...conv,
						output,
						agentId
					};
				} catch (error) {
					logger.warn({
						error,
						conversationId: conv.conversationId
					}, "Failed to fetch conversation output");
					return {
						...conv,
						output: null,
						agentId: null
					};
				}
			}));
			return {
				...item,
				conversations: conversationsWithOutput$1
			};
		}));
		const conversationsWithOutput = await Promise.all(conversationRelations.map(async (conv) => {
			try {
				const agentId = (await getConversation(runDbClient_default)({
					scopes: {
						tenantId,
						projectId
					},
					conversationId: conv.conversationId
				}))?.agentId || null;
				const assistantMessage = (await getMessagesByConversation(runDbClient_default)({
					scopes: {
						tenantId,
						projectId
					},
					conversationId: conv.conversationId,
					pagination: {
						page: 1,
						limit: 100
					}
				})).filter((msg) => msg.role === "assistant" || msg.role === "agent").sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())[0];
				let output = null;
				if (assistantMessage?.content) {
					if (typeof assistantMessage.content === "string") output = assistantMessage.content;
					else if (typeof assistantMessage.content === "object" && assistantMessage.content !== null && "text" in assistantMessage.content) output = typeof assistantMessage.content.text === "string" ? assistantMessage.content.text : null;
				}
				return {
					...conv,
					output,
					agentId
				};
			} catch (error) {
				logger.warn({
					error,
					conversationId: conv.conversationId
				}, "Failed to fetch conversation output");
				return {
					...conv,
					output: null,
					agentId: null
				};
			}
		}));
		return c.json({ data: {
			...run,
			runConfigName,
			conversations: conversationsWithOutput,
			items: itemsWithConversations
		} });
	} catch (error) {
		logger.error({
			error,
			tenantId,
			projectId,
			runId
		}, "Failed to get dataset run");
		return c.json(createApiError({
			code: "internal_server_error",
			message: "Failed to get dataset run"
		}), 500);
	}
});
var datasetRuns_default = app;

//#endregion
export { datasetRuns_default as default };