import {
	DeduplicateJoinsPlugin,
	HandleEmptyInListsPlugin,
	Kysely,
	type LogEvent,
	PostgresDialect,
	replaceWithNoncontingentExpression,
	type Transaction,
} from "kysely";
import { Pool } from "pg";
import { env } from "~/env";
import type Database from "~/schemas/Database";
import type PublicSchema from "~/schemas/public/PublicSchema";

/**
 * The database connection pool.
 */
const pool = new Pool({
	//connectionTimeoutMillis: 2000,
	database: env.POSTGRES_DB,
	host: env.PGHOST,
	//idleTimeoutMillis: 30000,
	max: 10,
	password: env.POSTGRES_PASSWORD,
	port: Number.parseInt(env.PGPORT),
	user: env.POSTGRES_USER,
});

pool.on("error", (err) => {
	const pgErr = err as { code?: string };
	// "admin_shutdown" error sent during backups
	const isAdminShutdown = pgErr.code === "57P01";

	if (isAdminShutdown) return;

	console.error("PG error:", err);
});

type Db = typeof db;

type Trx = Transaction<PublicSchema>;

export type Querier = Db | Trx;
/**
 * The database instance.
 */
export const db = new Kysely<Database>({
	dialect: new PostgresDialect({
		pool: pool,
	}),

	log: (_event) => {
		//DbLogger(event);
	},

	//plugins: [new SerializePlugin()]
	//plugins: [new CamelCasePlugin()],
	plugins: [
		new DeduplicateJoinsPlugin(),
		new HandleEmptyInListsPlugin({
			strategy: replaceWithNoncontingentExpression,
		}),
		//new ParseJSONResultsPlugin(),
	],
});

const _DbLogger = (event: LogEvent) => {
	if (
		event.level === "query" &&
		event.query.sql !== "begin" &&
		event.query.sql !== "commit"
	) {
		console.log();
		console.log("\x1b[33mquery:\x1b[0m", event.query.sql);
		console.log("\x1b[36mparams:\x1b[0m", event.query.parameters);
		//console.log("\x1b[32mtaken:\x1b[0m", event.queryDurationMillis, "ms");
	}
	if (event.level === "error") {
		console.error();
		console.error("\x1b[33mquery:\x1b[0m", event.query.sql);
		console.error("\x1b[36mparams:\x1b[0m", event.query.parameters);
		//console.error("\x1b[31merror:\x1b[0m", event.error);
	}
};
