import "server-only";
import { createHash } from "node:crypto";
import { EncryptJWT, jwtDecrypt } from "jose";
import {
  myinfoSnapshotSchema,
  type MyinfoSnapshot,
} from "./application-assessment";

const audience = "maxcredit-myinfo-assessment-v1";
const key = (secret: string) =>
  createHash("sha256").update(`${audience}:${secret}`).digest();
export async function issueMyinfoEvidence(
  snapshot: MyinfoSnapshot,
  secret: string,
  origin: string,
) {
  const parsed = myinfoSnapshotSchema.parse(snapshot);
  const expires =
    Math.floor(Date.parse(parsed.retrievedAt) / 1000) + 7 * 24 * 3600;
  const receipt = await new EncryptJWT({ snapshot: parsed })
    .setProtectedHeader({ alg: "dir", enc: "A256GCM" })
    .setIssuer(origin)
    .setAudience(audience)
    .setIssuedAt()
    .setExpirationTime(expires)
    .encrypt(key(secret));
  return {
    snapshot: parsed,
    receipt,
    expiresAt: new Date(expires * 1000).toISOString(),
  };
}
export async function readMyinfoEvidence(
  receipt: string,
  secret: string,
  origin: string,
): Promise<MyinfoSnapshot> {
  const { payload } = await jwtDecrypt(receipt, key(secret), {
    issuer: origin,
    audience,
    keyManagementAlgorithms: ["dir"],
    contentEncryptionAlgorithms: ["A256GCM"],
    requiredClaims: ["iat", "exp"],
    maxTokenAge: "7d",
  });
  const snapshot = myinfoSnapshotSchema.parse(payload.snapshot);
  if (Date.parse(snapshot.retrievedAt) > Date.now() + 30000)
    throw new Error("Invalid retrieval time");
  return snapshot;
}
