import { env } from "../env.js";
import runDbClient_default from "../data/db/runDbClient.js";
import { getLogger, isInternalServiceToken, validateAndGetApiKey, verifyInternalServiceAuthHeader } from "@inkeep/agents-core";
import { createMiddleware } from "hono/factory";
import { HTTPException } from "hono/http-exception";

//#region src/middleware/manageAuth.ts
const logger = getLogger("env-key-auth");
/**
* Middleware to authenticate API requests using Bearer token authentication
* Authentication priority:
* 1. Bypass secret (INKEEP_AGENTS_MANAGE_API_BYPASS_SECRET)
* 2. Better-auth session token (from device authorization flow)
* 3. Database API key
* 4. Internal service token
*/
const manageApiKeyAuth = () => createMiddleware(async (c, next) => {
	const authHeader = c.req.header("Authorization");
	if (!authHeader || !authHeader.startsWith("Bearer ")) throw new HTTPException(401, { message: "Missing or invalid authorization header. Expected: Bearer <api_key>" });
	const token = authHeader.substring(7);
	if (env.INKEEP_AGENTS_MANAGE_API_BYPASS_SECRET && token === env.INKEEP_AGENTS_MANAGE_API_BYPASS_SECRET) {
		logger.info({}, "Bypass secret authenticated successfully");
		c.set("userId", "system");
		c.set("userEmail", "system@internal");
		await next();
		return;
	}
	const auth = c.get("auth");
	if (auth) try {
		const headers$1 = new Headers();
		headers$1.set("Authorization", authHeader);
		const forwardedCookie = c.req.header("x-forwarded-cookie");
		const cookie = c.req.header("cookie");
		if (forwardedCookie) {
			headers$1.set("cookie", forwardedCookie);
			logger.debug({ source: "x-forwarded-cookie" }, "Using x-forwarded-cookie for session validation");
		} else if (cookie) {
			headers$1.set("cookie", cookie);
			logger.debug({ source: "cookie" }, "Using cookie for session validation");
		}
		const session = await auth.api.getSession({ headers: headers$1 });
		if (session?.user) {
			logger.info({ userId: session.user.id }, "Better-auth session authenticated successfully");
			c.set("userId", session.user.id);
			c.set("userEmail", session.user.email);
			await next();
			return;
		}
	} catch (error) {
		logger.debug({ error }, "Better-auth session validation failed, trying API key");
	}
	const validatedKey = await validateAndGetApiKey(token, runDbClient_default);
	if (validatedKey) {
		logger.info({ keyId: validatedKey.id }, "API key authenticated successfully");
		c.set("userId", `apikey:${validatedKey.id}`);
		c.set("userEmail", `apikey-${validatedKey.id}@internal`);
		c.set("tenantId", validatedKey.tenantId);
		await next();
		return;
	}
	if (isInternalServiceToken(token)) {
		const result = await verifyInternalServiceAuthHeader(authHeader);
		if (!result.valid || !result.payload) throw new HTTPException(401, { message: result.error || "Invalid internal service token" });
		logger.info({
			serviceId: result.payload.sub,
			tenantId: result.payload.tenantId,
			projectId: result.payload.projectId,
			userId: result.payload.userId
		}, "Internal service authenticated");
		c.set("userId", result.payload.userId || `system`);
		c.set("userEmail", `${result.payload.sub}@internal.inkeep`);
		if (result.payload.tenantId) c.set("tenantId", result.payload.tenantId);
		await next();
		return;
	}
	throw new HTTPException(401, { message: "Invalid Token" });
});

//#endregion
export { manageApiKeyAuth };