import { Client } from "pg";
import { db } from "../../../pkg/db/db.js";
import { type NewSetting, settings } from "../../../pkg/db/schema/settings.js";
import { createLogger } from "../../../pkg/logger/logger.js";
import { tryCatch } from "../../../pkg/utils/tryCatch.js";

export const addListeners = async () => {
	const log = createLogger({ module: "utils", subModule: "listeners" });
	const client = new Client({
		connectionString: process.env.DATABASE_URL_V1,
	});

	await client.connect();

	try {
		log.info({}, "Running the new log listener");
		await client.query(`
        CREATE OR REPLACE FUNCTION notify_new_log()
        RETURNS trigger AS $$
        BEGIN
        PERFORM pg_notify('logs_channel', row_to_json(NEW)::text);
        RETURN NEW;
        END;
        $$ LANGUAGE plpgsql;

        CREATE TRIGGER logs_notify_trigger
        AFTER INSERT ON logs
        FOR EACH ROW
        EXECUTE FUNCTION notify_new_log();
    `);
	} catch (e) {
		log.info({}, "log listener exist");
	}

	try {
		log.info({}, "Running the new label listener");
		await client.query(`
        CREATE OR REPLACE FUNCTION notify_new_label()
        RETURNS trigger AS $$
        BEGIN
        PERFORM pg_notify('label_channel', row_to_json(NEW)::text);
        RETURN NEW;
        END;
        $$ LANGUAGE plpgsql;

        CREATE TRIGGER label_notify_trigger
        AFTER INSERT ON prodlabels
        FOR EACH ROW
        EXECUTE FUNCTION notify_new_label();
    `);
	} catch (e) {
		log.info({}, "label listener exists");
	}

	try {
		log.info({}, "Bad data removing bad history data");
		await client.query(`
        DELETE FROM public."invHistoricalData" 
        WHERE upd_user = 'LST'
    `);
	} catch (e) {
		log.info({}, "Error deleting bad inv data");
	}
};

// all the migration stuff that will need to be moved later build 230 and above will need to remove
export const manualFixes = async () => {
	const log = createLogger({ module: "utils", subModule: "manual fixes" });
	const client = new Client({
		connectionString: `postgresql://${process.env.DATABASE_USER}:${process.env.DATABASE_PASSWORD}@${process.env.DATABASE_HOST}:${process.env.DATABASE_PORT}/${process.env.DATABASE_DB}`,
	});

	await client.connect();

	/**
	 * The fix to correct the constraint on the server data
	 */
	// const fixQuery = `ALTER TABLE "serverData" ADD CONSTRAINT "serverData_name_unique" UNIQUE("name");`;
	// try {
	// 	log.info({}, "Running the manual fix");
	// 	await client.query(fixQuery);
	// } catch (e) {
	// 	log.info({ error: e }, "Fix was not completed");
	// }
};

export const settingsMigrate = async () => {
	const log = createLogger({ module: "utils", subModule: "v1Migration" });
	const client = new Client({
		connectionString: process.env.DATABASE_URL_V1,
	});

	await client.connect();

	let settingsV1: NewSetting[] = [];

	try {
		log.info({}, "Running the manual fix");
		const s = await client.query("SELECT * FROM settings");

		settingsV1 = s.rows.map((i) => {
			return {
				name: i.name,
				value: i.value,
				description: i.description,
				moduleName: i.moduleName,
			};
		});
	} catch (e) {
		log.error({ error: e }, "There was an error getting the settings.");
	}

	const { data, error } = await tryCatch(
		db
			.insert(settings)
			.values(settingsV1)
			.onConflictDoNothing()
			.returning({ name: settings.name }),
	);

	if (error) {
		log.error({ error }, "There was an error adding new settings");
	}

	if (data) {
		log.info({ newSettingsAdded: data }, "New settings added");
	}
};

// migrations after 230 go below here so we can keep this inline.
