import { Provider, DynamicModule } from '@nestjs/common';

/**
 * AuthModule — DynamicModule factory for the auth subsystem.
 *
 * Wires the pluggable backends the subsystem ships with:
 *   - `ENCRYPTION_KEY`      → `EnvEncryptionKey` (AES-256-GCM from env)
 *   - `OAUTH_STATE_STORE`   → `MemoryOAuthStateStore` (dev/tests) or
 *                             `DrizzleOAuthStateStore` (prod, requires
 *                             DRIZZLE provider).
 *   - `AUTH_OPTIONS`        → resolved options bag (used by AuthController
 *                             for `redirectUriBase`).
 *
 * The connection-store ports (`AUTH_CONNECTION_READER`,
 * `AUTH_CONNECTION_TOKEN_WRITER`, `AUTH_CONNECTION_GRANT_SINK`),
 * `AUTH_USER_CONTEXT`, and `STRATEGY_REGISTRY` are deliberately **not**
 * wired here — they are always consumer-specific:
 *   - connection-store ports adapt the consumer's `connections` storage;
 *   - `IUserContext` adapts the app's session/JWT scheme;
 *   - `STRATEGY_REGISTRY` is populated from the per-provider strategy
 *     classes the consumer maintains.
 *
 * Consumers provide them in their app module (or by importing the
 * `auth-integrations` starter, which binds the three connection-store
 * ports off a single canonical entity).
 *
 * Usage in AppModule:
 * ```typescript
 * AuthModule.forRoot({
 *   encryptionKey: 'env',
 *   oauthStateStore: 'memory',          // or 'drizzle'
 *   enableController: true,
 *   redirectUriBase: 'http://localhost:3000',
 * });
 * ```
 *
 * `global: true` means other modules don't need to re-import AuthModule to
 * inject the auth tokens.
 */

type EncryptionKeyChoice = 'env' | Omit<Provider, 'provide'>;
type OAuthStateStoreChoice = 'memory' | 'drizzle' | Omit<Provider, 'provide'>;
interface AuthModuleOptions {
    /** `'env'` (default) or a full provider definition (e.g. `{ useClass: MyKmsEncryptionKey }`). */
    encryptionKey?: EncryptionKeyChoice;
    /**
     * `'memory'` (default — tests/dev) or `'drizzle'` (prod, requires DRIZZLE
     * provider) or a full provider definition for a custom impl.
     */
    oauthStateStore?: OAuthStateStoreChoice;
    /**
     * Mount `AuthController` (`/auth/:provider/connect` + `/callback`).
     * Default `false` — apps that hand-roll connect/callback (rare) or that
     * use the subsystem only for the refresh path can opt out.
     */
    enableController?: boolean;
    /**
     * Public base URL of the API server. Used to construct per-provider
     * callback URIs as `${redirectUriBase}/auth/:provider/callback`.
     * Required when `enableController: true`.
     */
    redirectUriBase?: string;
}
declare class AuthModule {
    static forRoot(options?: AuthModuleOptions): DynamicModule;
}

export { AuthModule, type AuthModuleOptions };
