/**
 * Apple OAuth id_token verification via JWKS.
 *
 * Apple quirk: user name is only sent on FIRST sign-in. The client must
 * forward displayName and we cache it immediately during account creation.
 */

import { createRemoteJWKSet, jwtVerify } from 'jose';
import { config } from '../../../lib/config.js';
import type { OAuthVerifiedIdentity } from './types.js';

const APPLE_JWKS_URI = 'https://appleid.apple.com/auth/keys';
const APPLE_ISSUER = 'https://appleid.apple.com';

let _jwks: ReturnType<typeof createRemoteJWKSet> | null = null;

function getJwks() {
  if (!_jwks) {
    _jwks = createRemoteJWKSet(new URL(APPLE_JWKS_URI));
  }
  return _jwks;
}

/** @internal Override JWKS for testing — do not use in production code. */
export function _setJwks(jwks: ReturnType<typeof createRemoteJWKSet>): void {
  _jwks = jwks;
}

/** @internal Reset JWKS to default for testing — do not use in production code. */
export function _resetJwks(): void {
  _jwks = null;
}

export async function verifyAppleIdToken(
  idToken: string,
  clientDisplayName?: string
): Promise<OAuthVerifiedIdentity> {
  const clientId = config.APPLE_CLIENT_ID;
  if (!clientId) {
    throw new Error('APPLE_CLIENT_ID is not configured');
  }

  const { payload } = await jwtVerify(idToken, getJwks(), {
    issuer: APPLE_ISSUER,
    audience: clientId,
  });

  const email = payload.email as string | undefined;
  const sub = payload.sub;
  if (!email || !sub) {
    throw new Error('Apple id_token missing email or sub');
  }

  return {
    provider: 'apple',
    providerUserId: sub,
    email: email.toLowerCase(),
    emailVerified: (payload.email_verified === 'true' ||
      payload.email_verified === true) as boolean,
    displayName: clientDisplayName ?? undefined,
  };
}
