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

//#region src/data-access/runtime/feedback.ts
const getFeedbackById = (db) => async (params) => {
	const [result] = await db.select({
		id: feedback.id,
		conversationId: feedback.conversationId,
		messageId: feedback.messageId,
		type: feedback.type,
		details: feedback.details,
		createdAt: feedback.createdAt,
		updatedAt: feedback.updatedAt
	}).from(feedback).where(and(projectScopedWhere(feedback, params.scopes), eq(feedback.id, params.feedbackId))).limit(1);
	return result;
};
const listFeedbackByConversation = (db) => async (params) => {
	return listFeedback(db)({
		scopes: params.scopes,
		conversationId: params.conversationId,
		messageId: params.messageId,
		pagination: params.pagination
	});
};
const listFeedback = (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 = [projectScopedWhere(feedback, params.scopes)];
	if (params.conversationId) conditions.push(eq(feedback.conversationId, params.conversationId));
	if (params.messageId) conditions.push(eq(feedback.messageId, params.messageId));
	if (params.type) conditions.push(eq(feedback.type, params.type));
	if (params.startDate) conditions.push(gte(feedback.createdAt, params.startDate));
	if (params.endDate) conditions.push(lte(feedback.createdAt, params.endDate));
	if (params.agentId) conditions.push(eq(conversations.agentId, params.agentId));
	const whereClause = and(...conditions);
	const conversationsJoin = [
		eq(feedback.tenantId, conversations.tenantId),
		eq(feedback.projectId, conversations.projectId),
		eq(feedback.conversationId, conversations.id)
	];
	const countQuery = db.select({ count: count() }).from(feedback);
	if (params.agentId) countQuery.leftJoin(conversations, and(...conversationsJoin));
	const [items, total] = await Promise.all([db.select({
		id: feedback.id,
		conversationId: feedback.conversationId,
		messageId: feedback.messageId,
		type: feedback.type,
		details: feedback.details,
		createdAt: feedback.createdAt,
		updatedAt: feedback.updatedAt,
		agentId: conversations.agentId
	}).from(feedback).leftJoin(conversations, and(...conversationsJoin)).where(whereClause).limit(limit).offset(offset).orderBy(desc(feedback.createdAt)), countQuery.where(whereClause)]);
	return {
		feedback: items,
		total: typeof total[0]?.count === "string" ? Number.parseInt(total[0].count, 10) : total[0]?.count ?? 0
	};
};
const getFeedbackByIds = (db) => async (params) => {
	if (params.feedbackIds.length === 0) return [];
	const conversationsJoin = [
		eq(feedback.tenantId, conversations.tenantId),
		eq(feedback.projectId, conversations.projectId),
		eq(feedback.conversationId, conversations.id)
	];
	return db.select({
		id: feedback.id,
		conversationId: feedback.conversationId,
		type: feedback.type,
		details: feedback.details,
		createdAt: feedback.createdAt,
		agentId: conversations.agentId
	}).from(feedback).leftJoin(conversations, and(...conversationsJoin)).where(and(projectScopedWhere(feedback, params.scopes), inArray(feedback.id, params.feedbackIds)));
};
const createFeedback = (db) => async (params) => {
	const now = (/* @__PURE__ */ new Date()).toISOString();
	const [created] = await db.insert(feedback).values({
		...params,
		createdAt: now,
		updatedAt: now
	}).returning();
	return created;
};
const createFeedbackBulk = (db) => async (items) => {
	if (items.length === 0) return [];
	const now = (/* @__PURE__ */ new Date()).toISOString();
	const values = items.map((item) => ({
		...item,
		createdAt: now,
		updatedAt: now
	}));
	return db.insert(feedback).values(values).returning();
};
const updateFeedback = (db) => async (params) => {
	const now = (/* @__PURE__ */ new Date()).toISOString();
	const [updated] = await db.update(feedback).set({
		...params.data,
		updatedAt: now
	}).where(and(projectScopedWhere(feedback, params.scopes), eq(feedback.id, params.feedbackId))).returning();
	return updated;
};
const deleteFeedback = (db) => async (params) => {
	const [deleted] = await db.delete(feedback).where(and(projectScopedWhere(feedback, params.scopes), eq(feedback.id, params.feedbackId))).returning();
	return deleted;
};

//#endregion
export { createFeedback, createFeedbackBulk, deleteFeedback, getFeedbackById, getFeedbackByIds, listFeedback, listFeedbackByConversation, updateFeedback };