import { Client, ok } from "@atcute/client";
import { mainSchema as getServiceAuthSchema } from "@atcute/atproto/types/server/getServiceAuth";
import type { Nsid } from "@atcute/lexicons/syntax";
import type { OAuthUserAgent } from "@atcute/oauth-browser-client";

export const createClient = (agent: OAuthUserAgent): Client => new Client({ handler: agent });

export interface ServiceAuthOptions {
	// service did for the jwt aud claim
	aud: string;
	lxm: string;
	// clamped to at least 60s, matching appview's service client.
	expiresInSeconds?: number;
}

// did:web service id, with ports percent-encoded like serviceauth didweb.
export const serviceDidForHost = (host: string): string => `did:web:${host.replace(/:/g, "%3A")}`;

// mint a service-auth jwt for knot/spindle xrpc calls.
export const mintServiceAuth = async (
	agent: OAuthUserAgent,
	{ aud, lxm, expiresInSeconds = 60 }: ServiceAuthOptions
): Promise<string> => {
	const client = createClient(agent);
	const exp = Math.floor(Date.now() / 1000) + Math.max(expiresInSeconds, 60);
	const { token } = await ok(
		client.call(getServiceAuthSchema, {
			params: { aud, exp, lxm: lxm as Nsid }
		})
	);
	return token;
};
