import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import { toNodeHandler } from "better-auth/node";
import express from "express";
import { createProxyMiddleware } from "http-proxy-middleware";
import morgan from "morgan";
import { umamiConfig } from "./configs/umami.config.js";
import { createLogger } from "./logger/logger.controller.js";
import { routeHitMiddleware } from "./middleware/routeHit.middleware.js";
import { setupRoutes } from "./routeHandler.routes.js";
import { auth } from "./utils/auth.utils.js";
import { lstCors } from "./utils/cors.utils.js";
import { getAppVersion } from "./utils/version.utils.js";

const createApp = async () => {
	const log = createLogger({ module: "system", subModule: "main start" });
	const app = express();
	let baseUrl = "";

	if (process.env.NODE_ENV?.trim() !== "production") {
		baseUrl = "/lst";
	}

	// if we are running un docker lets use this.
	if (process.env.RUNNING_IN_DOCKER) {
		baseUrl = "/lst";
	}

	const __filename = fileURLToPath(import.meta.url);
	const __dirname = dirname(__filename);

	// well leave this active so we can monitor it to validate
	app.use(morgan("dev"));
	app.set("trust proxy", true);
	app.use(lstCors());
	app.use(routeHitMiddleware);
	app.all(`${baseUrl}/api/auth/*splat`, toNodeHandler(auth));
	app.use(express.json());

	const version = await getAppVersion();
	app.get(`${baseUrl}/api/lst-config.js`, (_, res) => {
		res.type("application/javascript");
		res.setHeader("Cache-Control", "no-store");

		res.send(`
		window.LST_CONFIG = {
			appName: ${JSON.stringify(umamiConfig.appName ?? "LST")},
			site: ${JSON.stringify(umamiConfig.site ?? "unknown")},
			server: ${JSON.stringify(umamiConfig.server ?? "unknown")},
			appVersion: ${JSON.stringify(umamiConfig.appVersion ?? "dev")},
			umamiHost: ${JSON.stringify(umamiConfig.umamiHost ?? "")},
			umamiWebsiteId: ${JSON.stringify(umamiConfig.umamiWebsiteId ?? "")},
			timezone: ${JSON.stringify(process.env.TIMEZONE ?? "America/Chicago")},
			version: ${JSON.stringify(version.version)},
			lastBuildTIme: ${JSON.stringify(version.lastBuildTime)}
		};
	`);
	});

	setupRoutes(baseUrl, app);

	// point to the ccc
	// TODO: gate this behind a feature switch
	app.use(
		baseUrl + "/ccc",
		createProxyMiddleware({
			target: `http://localhost:${process.env.CCC || "5000"}`,
			changeOrigin: true,
			pathRewrite: (path, _) => {
				return path.replace(`${baseUrl}/ccc`, "");
			},
			headers: {
				"X-Forwarded-By": "express-proxy",
			},
		}),
	);

	app.use(
		`${baseUrl}/app`,
		express.static(join(__dirname, "../frontend/dist")),
	);

	app.get(`${baseUrl}/app/*splat`, (_, res) => {
		res.sendFile(join(__dirname, "../frontend/dist/index.html"));
	});

	app.all("*foo", (_, res) => {
		res.status(400).json({
			message:
				"You have encountered a route that dose not exist, please check the url and try again",
		});
	});

	log.info("Lst app created");
	return { app, baseUrl };
};

export default createApp;
