import { Inject, Injectable, OnModuleInit } from '@nestjs/common';
import { createRemoteJWKSet } from 'jose';
import type { JWTVerifyGetKey } from 'jose';
import { APP_ENVIRONMENT } from '../../configuration/src';
import type { AppEnvironment } from '../../configuration/src';

interface OidcDiscoveryDocument {
  jwks_uri: string;
}

@Injectable()
export class OidcDiscoveryService implements OnModuleInit {
  private verificationKeySet: JWTVerifyGetKey | undefined;

  constructor(
    @Inject(APP_ENVIRONMENT) private readonly environment: AppEnvironment,
  ) {}

  async onModuleInit(): Promise<void> {
    const issuer = this.environment.oidcIssuer.replace(/\/$/, '');
    const response = await fetch(`${issuer}/.well-known/openid-configuration`);
    if (!response.ok) {
      throw new Error(
        `Failed to fetch OIDC discovery document: HTTP ${response.status}`,
      );
    }
    const document = (await response.json()) as OidcDiscoveryDocument;
    this.verificationKeySet = createRemoteJWKSet(new URL(document.jwks_uri));
  }

  getIssuer(): string {
    return this.environment.oidcIssuer;
  }

  getAudience(): string {
    return this.environment.oidcAudience;
  }

  getVerificationKeySet(): JWTVerifyGetKey {
    if (!this.verificationKeySet) {
      throw new Error('OIDC discovery has not completed yet');
    }
    return this.verificationKeySet;
  }
}
