import { and, eq } from "drizzle-orm";
import { integer, pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core";
//#region src/schema.ts
const supportMessages = pgTable("support_messages", {
	id: uuid("id").primaryKey().defaultRandom(),
	parentType: text("parent_type").notNull(),
	parentId: text("parent_id").notNull(),
	authorType: text("author_type").notNull(),
	body: text("body").notNull(),
	visibility: text("visibility"),
	createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
});
const supportStateTransitions = pgTable("support_state_transitions", {
	id: uuid("id").primaryKey().defaultRandom(),
	parentType: text("parent_type").notNull(),
	parentId: text("parent_id").notNull(),
	fromStatus: text("from_status").notNull(),
	toStatus: text("to_status").notNull(),
	actorId: text("actor_id").notNull(),
	reason: text("reason"),
	at: timestamp("at", { withTimezone: true }).notNull().defaultNow()
});
const supportAttachments = pgTable("support_attachments", {
	id: uuid("id").primaryKey().defaultRandom(),
	parentType: text("parent_type").notNull(),
	parentId: text("parent_id").notNull(),
	objectKey: text("object_key").notNull(),
	fileName: text("file_name"),
	mimeType: text("mime_type"),
	createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
});
const slaPolicies = pgTable("sla_policies", {
	scopeKey: text("scope_key").primaryKey(),
	target: text("target").notNull(),
	dueMinutes: integer("due_minutes").notNull()
});
const helpdeskSchema = {
	supportMessages,
	supportStateTransitions,
	supportAttachments,
	slaPolicies
};
//#endregion
//#region src/attachments.ts
async function addAttachment(tx, key, input) {
	const [row] = await tx.insert(supportAttachments).values({
		parentType: key.parentType,
		parentId: key.parentId,
		objectKey: input.objectKey,
		fileName: input.fileName ?? null,
		mimeType: input.mimeType ?? null
	}).returning();
	if (!row) throw new Error("addAttachment: insert returned no row");
	return row;
}
async function listAttachments(tx, key) {
	return tx.select().from(supportAttachments).where(and(eq(supportAttachments.parentType, key.parentType), eq(supportAttachments.parentId, key.parentId)));
}
//#endregion
//#region src/messages.ts
async function postMessage(tx, key, input) {
	const [row] = await tx.insert(supportMessages).values({
		parentType: key.parentType,
		parentId: key.parentId,
		authorType: input.authorType,
		body: input.body,
		visibility: input.visibility ?? null
	}).returning();
	if (!row) throw new Error("postMessage: insert returned no row");
	return row;
}
async function listMessages(tx, key) {
	return tx.select().from(supportMessages).where(and(eq(supportMessages.parentType, key.parentType), eq(supportMessages.parentId, key.parentId)));
}
//#endregion
//#region src/sla.ts
function computeDue(policy, from) {
	return new Date(from.getTime() + policy.dueMinutes * 6e4);
}
function isBreached(dueAt, now) {
	return now.getTime() > dueAt.getTime();
}
//#endregion
//#region src/transitions.ts
async function appendTransition(tx, key, input) {
	const [row] = await tx.insert(supportStateTransitions).values({
		parentType: key.parentType,
		parentId: key.parentId,
		fromStatus: input.fromStatus,
		toStatus: input.toStatus,
		actorId: input.actorId,
		reason: input.reason ?? null,
		at: input.at ?? /* @__PURE__ */ new Date()
	}).returning();
	if (!row) throw new Error("appendTransition: insert returned no row");
	return row;
}
async function listTransitions(tx, key) {
	return tx.select().from(supportStateTransitions).where(and(eq(supportStateTransitions.parentType, key.parentType), eq(supportStateTransitions.parentId, key.parentId)));
}
//#endregion
//#region src/transition-validator.ts
function isValidTransition(adjacency, from, to, predicate, ctx) {
	if (!adjacency[from]?.includes(to)) return false;
	if (predicate && !predicate(ctx)) return false;
	return true;
}
//#endregion
export { addAttachment, appendTransition, computeDue, helpdeskSchema, isBreached, isValidTransition, listAttachments, listMessages, listTransitions, postMessage, slaPolicies, supportAttachments, supportMessages, supportStateTransitions };
