import { getLogger } from "./logger.js";
import { generateId } from "./conversations.js";
import { randomBytes, scrypt, timingSafeEqual } from "node:crypto";
import { customAlphabet } from "nanoid";
import { promisify } from "node:util";

//#region src/utils/apiKeys.ts
const scryptAsync = promisify(scrypt);
const logger = getLogger("api-key");
const API_KEY_LENGTH = 32;
const SALT_LENGTH = 32;
const KEY_LENGTH = 64;
const generatePublicId = customAlphabet("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-", 12);
/**
* Generate a new API key with secure random bytes
*/
async function generateApiKey() {
	const publicId = generatePublicId();
	const key = `sk_${publicId}.${randomBytes(API_KEY_LENGTH).toString("base64url")}`;
	const keyPrefix = key.substring(0, 12);
	const keyHash = await hashApiKey(key);
	return {
		id: generateId(),
		publicId,
		key,
		keyHash,
		keyPrefix
	};
}
const getMetadataFromApiKey = (key) => {
	const parts = key.split(".");
	if (parts.length !== 2) return null;
	const segments = parts[0].split("_");
	if (segments.length < 3) return null;
	return {
		tenantId: segments[1],
		projectId: segments[2]
	};
};
/**
* Hash an API key using scrypt
*/
async function hashApiKey(key) {
	const salt = randomBytes(SALT_LENGTH);
	const hashedBuffer = await scryptAsync(key, salt, KEY_LENGTH);
	return Buffer.concat([salt, hashedBuffer]).toString("base64");
}
/**
* Validate an API key against its hash
*/
async function validateApiKey(key, storedHash) {
	try {
		const combined = Buffer.from(storedHash, "base64");
		const salt = combined.subarray(0, SALT_LENGTH);
		return timingSafeEqual(combined.subarray(SALT_LENGTH), await scryptAsync(key, salt, KEY_LENGTH));
	} catch (error) {
		logger.error({ error }, "Error validating API key");
		return false;
	}
}
/**
* Check if an API key has expired
*/
function isApiKeyExpired(expiresAt) {
	if (!expiresAt) return false;
	const expirationDate = new Date(expiresAt);
	return /* @__PURE__ */ new Date() > expirationDate;
}
/**
* Extract the publicId from an API key
*/
function extractPublicId(key) {
	try {
		const parts = key.split(".");
		if (parts.length !== 2) return null;
		const segments = parts[0].split("_");
		if (segments.length < 2) return null;
		const publicId = segments[segments.length - 1];
		if (publicId.length !== 12) return null;
		return publicId;
	} catch {
		return null;
	}
}
/**
* Mask an API key for display (show only prefix and last 4 chars)
*/
function maskApiKey(keyPrefix) {
	return `${keyPrefix}...`;
}
function generateAppCredential() {
	return { id: `app_${generateId()}` };
}
function sanitizeAppConfig(app) {
	if (!app || typeof app !== "object") return app;
	const { tenantId, ...rest } = app;
	return rest;
}

//#endregion
export { extractPublicId, generateApiKey, generateAppCredential, getMetadataFromApiKey, hashApiKey, isApiKeyExpired, maskApiKey, sanitizeAppConfig, validateApiKey };