import { eq, sql } from "drizzle-orm";
import { type Request, type Response, Router } from "express";
import { db } from "../db/db.controller.js";
import { settings } from "../db/schema/settings.schema.js";

import { apiReturn } from "../utils/returnHelper.utils.js";
import { tryCatch } from "../utils/trycatch.utils.js";
import { featureControl } from "./settingsFeatures.controller.js";

// 	// TODO: when the setting is a system we will need to force an app restart
// 	// TODO: when the setting is standard we don't do anything.
// };

const r = Router();

r.patch("/:name", async (req: Request, res: Response) => {
	const { name } = req.params;
	const updates: Record<string, unknown | null> = {};
	// lets see if we even have a setting name

	const { data: sName, error: sError } = await tryCatch(
		db
			.select()
			.from(settings)
			.where(eq(settings.name, name ?? "")),
	);

	if (sError) {
		return apiReturn(res, {
			success: false,
			level: "error",
			module: "system",
			subModule: "settings",
			message: `There was an error checking the name of the setting`,
			data: [sError],
			status: 400,
		});
	}

	if (sName?.length === 0) {
		return apiReturn(res, {
			success: false,
			level: "error",
			module: "system",
			subModule: "settings",
			message: `The setting "${name}" dose not appear to be a valid setting please check the name and try again. `,
			data: [],
			status: 400,
		});
	}

	// manage the actual setting. we will still do an upsert just in case we strangely get past everything

	if (req.body?.value !== undefined) {
		updates.value = req.body.value;
	}

	if (req.body?.description !== undefined) {
		updates.description = req.body.description;
	}

	if (req.body?.moduleName !== undefined) {
		updates.moduleName = req.body.moduleName;
	}

	if (req.body?.active !== undefined) {
		updates.active = req.body.active === "true";
	}

	if (req.body?.roles !== undefined) {
		updates.roles = req.body.roles;
	}

	if (req.body?.settingType !== undefined) {
		updates.settingType = req.body.settingType;
	}

	updates.upd_user = req.user?.username || "lst_user";
	updates.upd_date = sql`NOW()`;

	const updatedSetting = await db
		.update(settings)
		.set(updates)
		.where(eq(settings.name, name ?? ""))
		.returning();

	// the switch statment will only run when the setting actually updates
	switch (updatedSetting[0]?.settingType) {
		case "feature":
			await featureControl(updatedSetting[0]);
			break;
		case "system":
			// TODO: add the system control logic in to restart the app if not in dev mode
			break;
		default:
			break;
	}

	return apiReturn(res, {
		success: true,
		level: "info",
		module: "system",
		subModule: "settings",
		message: `Setting "${name}" Was just updated. `,
		data: updatedSetting,
		status: 200,
	});
});

export default r;
