import { apps } from "../../db/runtime/runtime-schema.js";
import { projectScopedWhere, tenantScopedWhere } from "../manage/scope-helpers.js";
import { and, count, desc, eq, inArray } from "drizzle-orm";

//#region src/data-access/runtime/apps.ts
const getAppById = (db) => async (id) => {
	return await db.query.apps.findFirst({ where: eq(apps.id, id) });
};
const updateAppLastUsed = (db) => async (id) => {
	await db.update(apps).set({ lastUsedAt: (/* @__PURE__ */ new Date()).toISOString() }).where(eq(apps.id, id));
};
const getAppByIdForTenant = (db) => async (params) => {
	return db.query.apps.findFirst({ where: and(eq(apps.id, params.id), tenantScopedWhere(apps, params.scopes)) });
};
const getAppByIdForProject = (db) => async (params) => {
	return db.query.apps.findFirst({ where: and(eq(apps.id, params.id), projectScopedWhere(apps, params.scopes)) });
};
const listAppsPaginated = (db) => async (params) => {
	const page = params.pagination?.page || 1;
	const limit = Math.min(params.pagination?.limit || 10, 100);
	const offset = (page - 1) * limit;
	const conditions = [tenantScopedWhere(apps, params.scopes)];
	if (params.scopes.projectIds && params.scopes.projectIds.length > 0) conditions.push(inArray(apps.projectId, params.scopes.projectIds));
	if (params.type) conditions.push(eq(apps.type, params.type));
	const whereClause = and(...conditions);
	const [data, totalResult] = await Promise.all([db.select().from(apps).where(whereClause).limit(limit).offset(offset).orderBy(desc(apps.createdAt)), db.select({ count: count() }).from(apps).where(whereClause)]);
	const total = totalResult[0]?.count || 0;
	const totalNumber = typeof total === "string" ? Number.parseInt(total, 10) : total;
	return {
		data,
		pagination: {
			page,
			limit,
			total: totalNumber,
			pages: Math.ceil(totalNumber / limit)
		}
	};
};
const createApp = (db) => async (params) => {
	const now = (/* @__PURE__ */ new Date()).toISOString();
	const [app] = await db.insert(apps).values({
		...params,
		createdAt: now,
		updatedAt: now
	}).returning();
	return app;
};
const _updateApp = (db, scopeWhere) => async (id, data) => {
	const now = (/* @__PURE__ */ new Date()).toISOString();
	const [updatedApp] = await db.update(apps).set({
		...data,
		updatedAt: now
	}).where(and(eq(apps.id, id), scopeWhere)).returning();
	return updatedApp;
};
const _deleteApp = (db, scopeWhere) => async (id) => {
	return (await db.delete(apps).where(and(eq(apps.id, id), scopeWhere)).returning()).length > 0;
};
const updateAppForTenant = (db) => async (params) => _updateApp(db, tenantScopedWhere(apps, params.scopes))(params.id, params.data);
const updateAppForProject = (db) => async (params) => _updateApp(db, projectScopedWhere(apps, params.scopes))(params.id, params.data);
const deleteAppForTenant = (db) => async (params) => _deleteApp(db, tenantScopedWhere(apps, params.scopes))(params.id);
const deleteAppForProject = (db) => async (params) => _deleteApp(db, projectScopedWhere(apps, params.scopes))(params.id);
const deleteAppsByProject = (db) => async (tenantId, projectId) => {
	return (await db.delete(apps).where(and(tenantScopedWhere(apps, { tenantId }), eq(apps.projectId, projectId))).returning()).length;
};
const clearAppDefaultsByProject = (db) => async (tenantId, projectId) => {
	return (await db.update(apps).set({
		defaultProjectId: null,
		defaultAgentId: null,
		updatedAt: (/* @__PURE__ */ new Date()).toISOString()
	}).where(and(tenantScopedWhere(apps, { tenantId }), eq(apps.defaultProjectId, projectId))).returning()).length;
};
const clearAppDefaultsByAgent = (db) => async (tenantId, agentId) => {
	return (await db.update(apps).set({
		defaultAgentId: null,
		updatedAt: (/* @__PURE__ */ new Date()).toISOString()
	}).where(and(tenantScopedWhere(apps, { tenantId }), eq(apps.defaultAgentId, agentId))).returning()).length;
};
const getAppAuthKeysForProject = (db) => async (params) => {
	return (await db.select({
		config: apps.config,
		type: apps.type
	}).from(apps).where(and(eq(apps.id, params.id), projectScopedWhere(apps, params.scopes))).limit(1))[0];
};
const updateAppAuthKeysForProject = (db) => async (params) => {
	const now = (/* @__PURE__ */ new Date()).toISOString();
	const [updated] = await db.update(apps).set({
		config: params.config,
		updatedAt: now
	}).where(and(eq(apps.id, params.id), projectScopedWhere(apps, params.scopes))).returning();
	return updated;
};
const updateApp = (db) => async (params) => {
	const now = (/* @__PURE__ */ new Date()).toISOString();
	const [updatedApp] = await db.update(apps).set({
		...params.data,
		updatedAt: now
	}).where(eq(apps.id, params.id)).returning();
	return updatedApp;
};
const deleteApp = (db) => async (id) => {
	if (!await getAppById(db)(id)) return false;
	await db.delete(apps).where(eq(apps.id, id));
	return true;
};

//#endregion
export { clearAppDefaultsByAgent, clearAppDefaultsByProject, createApp, deleteApp, deleteAppForProject, deleteAppForTenant, deleteAppsByProject, getAppAuthKeysForProject, getAppById, getAppByIdForProject, getAppByIdForTenant, listAppsPaginated, updateApp, updateAppAuthKeysForProject, updateAppForProject, updateAppForTenant, updateAppLastUsed };