/**
 * Type declarations for the `oidc-provider` library.
 * The library ships only JavaScript — we describe only the surface our code uses.
 * Keep this minimal; expand on demand rather than maintaining full types.
 */

declare module 'oidc-provider' {
	// ── Account shape required by findAccount ──────────────────────────────────
	export interface OidcAccount {
		accountId: string;
		claims: (scopes: string[]) => Record<string, unknown>;
	}

	// ── Cookies config ─────────────────────────────────────────────────────────
	export interface OidcCookieOptions {
		httpOnly?: boolean;
		sameSite?: 'lax' | 'strict' | 'none';
		path?: string;
		[key: string]: unknown;
	}

	// ── TTL values (seconds) ───────────────────────────────────────────────────
	export interface OidcTtlConfig {
		AccessToken?: number;
		RefreshToken?: number;
		AuthorizationCode?: number;
		AccessTokenLifetime?: number;
		Grant?: number;
		Session?: number;
		Interaction?: number;
		IdToken?: number;
		ClientCredentials?: number;
		DeviceCode?: number;
		BackchannelAuthentication?: number;
		RegistrationAccessToken?: number;
	}

	// ── Claims ─────────────────────────────────────────────────────────────────
	export interface OidcClaimsConfig {
		openid?: string[];
		profile?: string[];
		email?: string[];
		address?: string[];
		phone?: string[];
		[key: string]: string[] | undefined;
	}

	// ── Features ───────────────────────────────────────────────────────────────
	export interface OidcFeaturesConfig {
		devInteractions?: { enabled: boolean };
		introspection?: { enabled: boolean };
		revocation?: { enabled: boolean };
		rpInitiatedLogout?: { enabled: boolean };
		registration?: { enabled: boolean };
		claimsParameter?: { enabled: boolean };
		dPoP?: { enabled: boolean };
		resourceIndicators?: { enabled: boolean };
		richAuthorizationRequests?: { enabled: boolean };
		webMessageResponseMode?: { enabled: boolean };
		mTLS?: {
			enabled?: boolean;
			getCertificate?: (ctx: unknown) => unknown;
			certificateAuthorized?: (ctx: unknown) => boolean;
			certificateSubjectMatches?: (ctx: unknown, prop: string, value: string) => boolean;
		};
	}

	// ── Routes ─────────────────────────────────────────────────────────────────
	export interface OidcRoutesConfig {
		authorization?: string;
		token?: string;
		userinfo?: string;
		jwks?: string;
		introspection?: string;
		revocation?: string;
		end_session?: string;
		registration?: string;
		pushed_authorization_request?: string;
		code_verification?: string;
		device_authorization?: string;
		backchannel_authentication?: string;
	}

	// ── Interactions ───────────────────────────────────────────────────────────
	export interface OidcInteraction {
		uid: string;
	}
	export interface OidcInteractionsConfig {
		url?: (ctx: unknown, interaction: OidcInteraction) => string | Promise<string>;
		policy?: unknown;
	}

	// ── Adapter factory ────────────────────────────────────────────────────────
	export type OidcAdapterFactory = (name: string) => unknown;

	// ── Provider configuration (the only fields we actually set) ───────────────
	export interface OidcProviderConfiguration {
		adapter: OidcAdapterFactory;
		cookies: {
			keys: string[];
			long?: OidcCookieOptions;
			short?: OidcCookieOptions;
			names?: Record<string, string>;
		};
		jwks?: { keys: unknown[] } | { privateJwks?: unknown };
		claims?: OidcClaimsConfig;
		ttl?: OidcTtlConfig;
		features?: OidcFeaturesConfig;
		routes?: OidcRoutesConfig;
		interactions?: OidcInteractionsConfig;
		findAccount?: (ctx: unknown, sub: string) => Promise<OidcAccount>;
		clients?: unknown[];
		extraTokenClaims?: (ctx: unknown, token: unknown) => Record<string, unknown> | Promise<Record<string, unknown>>;
		extraAccessTokenClaims?: (ctx: unknown, token: unknown) => Record<string, unknown> | Promise<Record<string, unknown>>;
		extraJwtClaims?: (ctx: unknown, token: unknown) => Record<string, unknown> | Promise<Record<string, unknown>>;
		conformIdTokenClaims?: boolean;
		loadExistingGrant?: (ctx: unknown) => Promise<string | undefined>;
		grant?: (ctx: unknown) => unknown;
		prompt?: unknown;
		subjectTypes?: string[];
		allowEmptyLocalAccount?: boolean;
		revoke?: unknown;
		rotateRefreshToken?: boolean;
		clientBasedSigning?: boolean;
		// Allow any additional provider options
		extraProps?: boolean;
		[key: string]: unknown;
	}

	// ── Provider instance surface used in this project ─────────────────────────
	// We declare only the methods we use; `Provider` is the actual runtime class.
	// The intersection lets TypeScript accept `Provider` wherever IOidcProvider is expected.
	export type IOidcProvider = Provider & {
		cookieName: (kind: 'interaction' | 'resume' | 'session') => string;
		Interaction: {
			find: (uid: string) => Promise<unknown>;
			findByUid: (uid: string) => Promise<unknown>;
		};
		Session: {
			findByUid: (uid: string) => Promise<unknown>;
		};
		Grant: new (...args: unknown[]) => unknown;
	};

	export class Provider implements IOidcProvider {
		constructor(issuer: string, config: OidcProviderConfiguration);
		callback!: () => (req: unknown, res: unknown, next: unknown) => Promise<void>;
		interactionDetails!: (req: unknown, res: unknown) => Promise<unknown>;
		interactionFinished!: (
			req: unknown,
			res: unknown,
			result: unknown,
			options?: unknown,
		) => Promise<unknown>;
		interactionResult!: (
			req: unknown,
			res: unknown,
			result: unknown,
			options?: unknown,
		) => Promise<string>;
		cookieName!: (kind: 'interaction' | 'resume' | 'session') => string;
		Interaction!: {
			find: (uid: string) => Promise<unknown>;
			findByUid: (uid: string) => Promise<unknown>;
		};
		Session!: { findByUid: (uid: string) => Promise<unknown> };
		Grant!: new (...args: unknown[]) => unknown;
	}

	export default Provider;
}
