import postgres from "postgres";
import { createLogger } from "../logger/logger.controller.js";
import { bufferProcess } from "../system/system.prodAuditLog.utils.js";
import { handleDbNotification } from "./db.router.js";

const log = createLogger({
	module: "db",
	subModule: "notifications",
});

const CHANNELS = [
	"logs_inserted",
	// "labels_inserted",
	// "dock_scans_inserted",
] as const;

type DbNotificationChannel = (typeof CHANNELS)[number];

type DbNotificationPayload = {
	table: string;
	action: "INSERT" | "UPDATE" | "DELETE";
	id: string;
};

export async function startDbNotificationListener() {
	const sql = postgres({
		host: `${process.env.DATABASE_HOST}`,
		port: Number(process.env.DATABASE_PORT),
		database: `${process.env.DATABASE_DB}`,
		username: process.env.DATABASE_USER,
		password: process.env.DATABASE_PASSWORD,
	});

	for (const channel of CHANNELS) {
		await sql.listen(channel, async (rawPayload) => {
			await processNotification(channel, rawPayload);
		});

		log.info({ stack: { channel } }, `Listening for ${channel}`);
	}

	// server side only listeners
	await sql.listen("auditLog_inserted", async (rawPayload) => {
		bufferProcess(rawPayload);
	});
}

async function processNotification(
	channel: DbNotificationChannel,
	rawPayload: string,
) {
	try {
		const payload = JSON.parse(rawPayload) as DbNotificationPayload;

		await handleDbNotification({
			channel,
			payload,
		});
	} catch (e) {
		log.error(
			{ stack: { channel, rawPayload, e }, notify: true },
			"Failed processing DB notification",
		);
	}
}
