import { spawn } from "node:child_process";
import { eq, sql } from "drizzle-orm";
import { db } from "../db/db.controller.js";
import { serverData } from "../db/schema/serverData.schema.js";
import { appStats } from "../db/schema/stats.schema.js";
//import { createLogger } from "../logger/logger.controller.js";
import { emitBuildLog } from "./build.utils.js";
import { returnFunc } from "./returnHelper.utils.js";

// const log = createLogger({ module: "utils", subModule: "deploy" });
export let updating = false;

const updateServerBuildNumber = async (token: string) => {
	// get the current build
	const buildNum = await db.select().from(appStats);

	// update the build now

	await db
		.update(serverData)
		.set({ buildNumber: buildNum[0]?.currentBuild, lastUpdated: sql`NOW()` })
		.where(eq(serverData.plantToken, token));
};
export const runUpdate = ({
	server,
	destination,
	token,
}: {
	server: string;
	destination: string;
	token: string;
}) => {
	return new Promise((resolve, reject) => {
		updating = true;
		const scriptPath = process.env.UPDATE_SCRIPT_PATH;
		if (!scriptPath) {
			return returnFunc({
				success: true,
				level: "error",
				module: "utils",
				subModule: "deploy",
				message: "UPDATE_SCRIPT_PATH please make sure you have this set.",
				data: [],
				notify: true,
				room: "admin",
			});
		}

		const args = [
			"-ExecutionPolicy",
			"Bypass",
			"-File",
			scriptPath,
			"-Server",
			server,
			"-Destination",
			destination,
			"-Token",
			token,
			"-ADM_USER",
			process.env.DEV_USER ?? "",
			"-ADM_PASSWORD",
			process.env.DEV_PASSWORD ?? "",
			"-AppDir",
			process.env.DEV_DIR ?? "",
		];

		emitBuildLog(`Starting update for ${server}`);

		const child = spawn("powershell.exe", args, {
			shell: false,
		});

		child.stdout.on("data", (data) => {
			const lines = data.toString().split(/\r?\n/);
			for (const line of lines) {
				if (line.trim()) {
					emitBuildLog(line);
				}
			}
		});

		child.stderr.on("data", (data) => {
			const lines = data.toString().split(/\r?\n/);
			for (const line of lines) {
				if (line.trim()) {
					emitBuildLog(line, "error");
				}
			}
		});

		child.on("close", (code) => {
			if (code === 0) {
				emitBuildLog(`Update completed for ${server}`);
				updating = false;
				updateServerBuildNumber(token);
				resolve({
					success: true,
					message: `Update completed for ${server}`,
					data: [],
				});
			} else {
				emitBuildLog(`Update failed for ${server} (code ${code})`, "error");
				updating = false;
				reject({
					success: false,
					message: `Update failed for ${server} (code ${code})`,
					data: [],
				});
			}
		});

		child.on("error", (err) => {
			emitBuildLog(`Process error: ${err.message}`, "error");
			updating = false;
			reject({
				success: false,
				message: `${server}: Encountered an error while processing: ${err.message} `,
				data: err,
			});
		});
	});
};
