import { Writable } from "node:stream";

import pino, { type Logger } from "pino";
import { db } from "../db/db.controller.js";
import { logs } from "../db/schema/logs.schema.js";
import { tryCatch } from "../utils/trycatch.utils.js";
import { notifySystemIssue } from "./logger.notify.js";
//import build from "pino-abstract-transport";

export const logLevel = process.env.LOG_LEVEL || "info";

const pinoLogLevels: Record<number, string> = {
	10: "trace",
	20: "debug",
	30: "info",
	40: "warn",
	50: "error",
	60: "fatal",
};

// ✅ Custom DB writable stream
const dbStream = new Writable({
	objectMode: true,
	async write(chunk, _enc, callback) {
		try {
			const obj = JSON.parse(chunk.toString());

			const levelName = pinoLogLevels[obj.level] || "unknown";

			const res = await tryCatch(
				db
					.insert(logs)
					.values({
						level: levelName,
						module: obj?.module?.toLowerCase(),
						subModule: obj?.subModule?.toLowerCase(),
						hostname: obj?.hostname?.toLowerCase(),
						message: obj.msg,
						stack: obj?.stack || obj?.error, // this will add in the error or stack depending on how we pass it.
					})
					.returning(),
			);

			if (res.error) {
				console.error(res.error);
			}

			if (obj.notify) {
				notifySystemIssue(obj);
			}

			// if (obj.room) {
			// 	emitToRoom(obj.room, res.data ? res.data[0] : obj);
			// }
			// emitToRoom("logs", res.data ? res.data[0] : obj);
			callback();
		} catch (err) {
			console.error("DB log insert error:", err);
			callback();
		}
	},
});

const rootLogger: Logger = pino(
	{
		level: logLevel,
		redact: { paths: ["email", "password"], remove: true },
	},
	pino.multistream([
		{
			level: logLevel,
			stream: pino.transport({
				target: "pino-pretty",
				options: {
					colorize: true,
					singleLine: true,
				},
			}),
		},
		{
			level: logLevel,
			stream: dbStream,
		},
	]),
);
/**
 *
 *
 * example data to put in as a reference
 * rooms logs | labels | etc
 */
export const createLogger = (bindings: Record<string, unknown>): Logger => {
	return rootLogger.child(bindings);
};
