import { env } from "../env.js";
import { getLogger } from "./logger.js";
import { SignJWT, jwtVerify } from "jose";

//#region src/utils/jwt-helpers.ts
const logger = getLogger("jwt-helpers");
const DEV_SECRET = "insecure-dev-secret-change-in-production-min-32-chars";
/**
* Get the JWT signing secret from environment variables.
* Falls back to an insecure default in non-production environments.
*/
function getJwtSecret() {
	const secret = env.INKEEP_AGENTS_JWT_SIGNING_SECRET;
	if (!secret) {
		if (env.ENVIRONMENT === "production") throw new Error("INKEEP_AGENTS_JWT_SIGNING_SECRET environment variable is required in production");
		logger.warn("INKEEP_AGENTS_JWT_SIGNING_SECRET not set, using insecure default. DO NOT USE IN PRODUCTION!");
		return new TextEncoder().encode(DEV_SECRET);
	}
	return new TextEncoder().encode(secret);
}
/**
* Sign a JWT with the shared secret
*/
async function signJwt(options) {
	const secret = getJwtSecret();
	const builder = new SignJWT(options.claims || {}).setProtectedHeader({
		alg: "HS256",
		typ: "JWT"
	}).setIssuer(options.issuer).setSubject(options.subject).setIssuedAt().setExpirationTime(options.expiresIn || "5m");
	if (options.audience) builder.setAudience(options.audience);
	return builder.sign(secret);
}
/**
* Verify a JWT and return the raw payload
*/
async function verifyJwt(token, options) {
	const secret = getJwtSecret();
	try {
		const verifyOptions = {
			issuer: options.issuer,
			algorithms: ["HS256"]
		};
		if (options.audience) verifyOptions.audience = options.audience;
		const { payload } = await jwtVerify(token, secret, verifyOptions);
		return {
			valid: true,
			payload
		};
	} catch (error) {
		if (error instanceof Error) return {
			valid: false,
			error: error.message
		};
		return {
			valid: false,
			error: "Token verification failed"
		};
	}
}
/**
* Extract bearer token from Authorization header
*/
function extractBearerToken(authHeader) {
	if (!authHeader) return { error: "Missing Authorization header" };
	if (!authHeader.startsWith("Bearer ")) return { error: "Invalid Authorization header format. Expected: Bearer <token>" };
	const token = authHeader.substring(7);
	if (!token) return { error: "Empty token in Authorization header" };
	return { token };
}
/**
* Decode JWT payload without verification (for checking issuer before full verify)
*/
function decodeJwtPayload(token) {
	try {
		const parts = token.split(".");
		if (parts.length !== 3) return null;
		return JSON.parse(Buffer.from(parts[1], "base64url").toString());
	} catch {
		return null;
	}
}
/**
* Check if a token has a specific issuer (without full verification)
*/
function hasIssuer(token, issuer) {
	return decodeJwtPayload(token)?.iss === issuer;
}
/**
* Derive a deterministic kid from a PEM-encoded public key.
* The kid is a truncated SHA-256 hash prefixed with 'pg-'.
*/
async function deriveKidFromPublicKey(publicKeyPem) {
	const data = new TextEncoder().encode(publicKeyPem);
	const hashBuffer = await crypto.subtle.digest("SHA-256", data);
	return `pg-${Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("").substring(0, 12)}`;
}

//#endregion
export { decodeJwtPayload, deriveKidFromPublicKey, extractBearerToken, getJwtSecret, hasIssuer, signJwt, verifyJwt };