/**
 * Clerk Metadata Sync
 *
 * Stores key user data on Clerk's user metadata so it can be
 * referenced from Clerk context without querying Prisma.
 *
 * publicMetadata  — readable from frontend via useUser().user.publicMetadata
 * privateMetadata — server-only, via clerkClient backend SDK
 *
 * Clerk merges metadata at the top level — setting one key preserves others.
 */

import { logger } from "./logger";

/**
 * Update Clerk user metadata. Requires the Clerk user ID.
 * Non-fatal — logs errors but never throws, since Prisma is the source of truth.
 */
export async function syncToClerkMetadata(
  clerkUserId: string,
  opts: {
    publicMetadata?: Record<string, unknown>;
    privateMetadata?: Record<string, unknown>;
  },
): Promise<void> {
  try {
    const { clerkClient } = await import("@clerk/nextjs/server");
    const client = await clerkClient();

    await client.users.updateUser(clerkUserId, {
      publicMetadata: opts.publicMetadata ?? {},
      privateMetadata: opts.privateMetadata ?? {},
    });

    logger.info("Clerk metadata synced", {
      clerkUserId,
      publicKeys: Object.keys(opts.publicMetadata ?? {}),
      privateKeys: Object.keys(opts.privateMetadata ?? {}),
    });
  } catch (err) {
    logger.warn("Failed to sync metadata to Clerk (non-fatal)", {
      clerkUserId,
      error: err instanceof Error ? err.message : String(err),
    });
  }
}

/**
 * Get the current Clerk user ID from the request context.
 * Returns null if Clerk is not configured or user is not authenticated via Clerk.
 */
export async function getClerkUserId(): Promise<string | null> {
  try {
    const { currentUser } = await import("@clerk/nextjs/server");
    const user = await currentUser();
    return user?.id ?? null;
  } catch {
    return null;
  }
}
