// routeHit.middleware.ts

import type { NextFunction, Request, Response } from "express";
import {
	createRouteHit,
	shouldIgnoreRoute,
} from "../utils/analyticRouteHits.utils.js";

export function routeHitMiddleware(
	req: Request,
	res: Response,
	next: NextFunction,
) {
	const start = performance.now();

	res.on("finish", () => {
		const actualPath = getActualPath(req);

		if (shouldIgnoreRoute(actualPath)) {
			return;
		}

		const durationMs = Math.round(performance.now() - start);

		const routePattern = getRoutePattern(req) as string;
		const module = getModuleName(req);

		void createRouteHit({
			method: req.method,
			routePattern,
			actualPath,
			statusCode: res.statusCode,
			durationMs,
			module,

			// adjust these names to your Better Auth/session shape
			userId: req.user?.id ?? null,
			userEmail: req.user?.email ?? null,

			ipAddress: req.ip ?? null,
			userAgent: req.get("user-agent") ?? null,
		}).catch((err) => {
			console.error("Failed to save route hit", err);
		});
	});

	next();
}

function getActualPath(req: Request) {
	return req.originalUrl.split("?")[0] ?? req.path ?? "unknown";
}

function getRoutePattern(req: Request) {
	const baseUrl = req.baseUrl || "";
	const routePath = req.route?.path;

	if (typeof routePath === "string") {
		return `${baseUrl}${routePath}`;
	}

	return getActualPath(req);
}

function getModuleName(req: Request) {
	const path = req.originalUrl.split("?")[0];

	if (path?.includes("/printers")) return "printers";
	if (path?.includes("/releases")) return "releases";
	if (path?.includes("/quality")) return "quality";
	if (path?.includes("/scanner")) return "scanner";
	if (path?.includes("/settings")) return "settings";
	if (path?.includes("/users")) return "users";
	if (path?.includes("/mobile")) return "mobile";
	if (path?.includes("/servers")) return "servers";
	if (path?.includes("/logistics")) return "servers";
	if (path?.includes("/ocp")) return "ocp";
	if (path?.includes("/auth")) return "auth";
	if (path?.includes("/datamart")) return "datamart";
	if (path?.includes("/opendock")) return "opendock";

	return "unknown";
}
