import { SignJWT } from 'jose'

/**
 * Mint a short-lived HS256 JWT for `userId`, signed with the project's
 * legacy JWT secret. Used by `createClient()` to swap the request's
 * auth token when view-as is active, so RLS evaluates against the
 * impersonated user instead of the super-admin doing the impersonating.
 *
 * Why HS256 + the legacy secret: Supabase's auth service still accepts
 * tokens signed with the legacy HMAC secret (see Supabase dashboard
 * "Legacy JWT secret (still used)"). The newer asymmetric JWT Signing
 * Keys are the future direction but would add 50+ lines of key handling
 * for the same effect. If Supabase ever retires the legacy verification
 * path, this is the one function to swap.
 *
 * Claims mirror what Supabase Auth produces for a normal sign-in: sub
 * + role + aud + iss. We keep the lifetime to 5 minutes — a request
 * shouldn't outlive that, and there's no refresh-token plumbing on a
 * minted JWT.
 */
export async function mintJwtForUser(userId: string): Promise<string> {
  const secret = process.env.SUPABASE_JWT_SECRET
  if (!secret) {
    throw new Error(
      'SUPABASE_JWT_SECRET missing — view-as impersonation requires the legacy JWT secret in .env',
    )
  }
  const url = process.env.NEXT_PUBLIC_SUPABASE_URL!
  // iss matches what Supabase Auth uses: `${SUPABASE_URL}/auth/v1`.
  const iss = `${url.replace(/\/+$/, '')}/auth/v1`
  const key = new TextEncoder().encode(secret)
  return await new SignJWT({
    sub: userId,
    role: 'authenticated',
    aud: 'authenticated',
    iss,
  })
    .setProtectedHeader({ alg: 'HS256', typ: 'JWT' })
    .setIssuedAt()
    .setExpirationTime('5m')
    .sign(key)
}
