import { HashAlgorithm, Digits, CryptoPlugin, Base32Plugin, OTPGuardrails, OTPHooks } from '@otplib/core';
export { CryptoPlugin, Digits, HashAlgorithm, OTPResult, wrapResult, wrapResultAsync } from '@otplib/core';

/**
 * @otplib/totp
 *
 * Type definitions for TOTP implementation
 */

/**
 * TOTP configuration options
 *
 * All properties are optional for flexible class-based configuration.
 * Use `TOTPGenerateOptions` or `TOTPVerifyOptions` for function parameters
 * where certain fields are required.
 */
type TOTPOptions = {
    /** The shared secret key (Base32-encoded string or raw bytes) */
    readonly secret?: string | Uint8Array;
    /** Current Unix epoch timestamp in seconds (default: Date.now() / 1000) */
    readonly epoch?: number;
    /**
     * Initial Unix time to start counting time steps (default: 0)
     *
     * Per RFC 6238, T0 is the Unix time from which to start counting.
     * Most implementations use 0, but some systems may use a different start time.
     *
     * Formula: counter = floor((epoch - t0) / period)
     */
    readonly t0?: number;
    /** Time step in seconds (default: 30) */
    readonly period?: number;
    /** Hash algorithm to use (default: 'sha1') */
    readonly algorithm?: HashAlgorithm;
    /** Number of digits in the OTP code (default: 6) */
    readonly digits?: Digits;
    /** Crypto plugin to use for HMAC operations */
    readonly crypto?: CryptoPlugin;
    /** Base32 plugin to decode string secrets (required if secret is a string) */
    readonly base32?: Base32Plugin;
    /** Service provider name (for URI generation) */
    readonly issuer?: string;
    /** User identifier/email/username (for URI generation) */
    readonly label?: string;
    /**
     * Custom guardrails to override validation limits
     * Must be created via createGuardrails() factory
     * Use this carefully - see danger-zone documentation
     */
    readonly guardrails?: OTPGuardrails;
    /**
     * Hooks for customizing token encoding and validation.
     * Allows non-standard OTP variants (e.g., Steam Guard) to replace
     * the default numeric encoding with custom schemes.
     */
    readonly hooks?: OTPHooks;
};
/**
 * Required options for TOTP generation
 *
 * Requires `secret` and `crypto` for OTP generation.
 * Optional `guardrails` must be created via createGuardrails() factory.
 */
type TOTPGenerateOptions = TOTPOptions & {
    readonly secret: string | Uint8Array;
    readonly crypto: CryptoPlugin;
};
/**
 * Required options for TOTP verification
 *
 * Requires `secret`, `token`, and `crypto` for verification.
 */
type TOTPVerifyOptions = TOTPGenerateOptions & {
    /** The OTP token to verify */
    readonly token: string;
    /**
     * Time tolerance in seconds (default: 0 = current period only)
     *
     * Accepts tokens that were or will be valid within the specified tolerance
     * of the current time. This aligns with RFC 6238's transmission delay concept.
     *
     * @see {@link https://tools.ietf.org/html/rfc6238#section-5.2 | RFC 6238 Section 5.2}
     *
     * - Number: symmetric tolerance (same for past and future)
     *   `epochTolerance: 5` checks [epoch - 5, epoch + 5]
     *
     * - Tuple [past, future]: asymmetric tolerance
     *   `epochTolerance: [5, 0]` checks [epoch - 5, epoch] (RFC-compliant, past only)
     *   `epochTolerance: [5, 10]` checks [epoch - 5, epoch + 10]
     *
     * @example Recommended values by security level
     * ```typescript
     * // RFC-compliant (transmission delay only, past tokens)
     * epochTolerance: [5, 0]
     *
     * // High security (banking, critical systems)
     * epochTolerance: 5  // or [5, 5] symmetric
     *
     * // Standard (most 2FA implementations)
     * epochTolerance: 30
     *
     * // Lenient (poor network, user-friendly)
     * epochTolerance: 60
     * ```
     *
     * @example How tolerance works
     * ```
     * With period=30 and epochTolerance=[5, 0] (RFC-compliant):
     *
     * Period N-1         | Period N (current)  | Period N+1
     * [token A valid]    | [token B valid]     | [token C valid]
     *                    |                     |
     * At epoch in period N:
     * - If 0-5 sec into period:  A valid, B valid
     * - If 6-29 sec into period: B valid only
     * (Future tokens never accepted)
     * ```
     */
    readonly epochTolerance?: number | [number, number];
    /**
     * Minimum time step for replay protection (optional)
     *
     * Specifies an exclusive lower bound for valid time steps. Time steps less than
     * or equal to this value will be rejected during verification. This prevents
     * reuse of TOTP codes from previously verified time steps.
     *
     * Per RFC 6238, time step T = floor((CurrentUnixTime - T0) / X), where X is the period.
     * This is the time step number, not a Unix timestamp.
     *
     * **Validation:**
     * - Must be a non-negative integer
     * - Cannot be greater than current time step plus window
     * - Throws on invalid values (fail-fast for development)
     *
     * **Use case:** Track the time step from each successful verification and pass it
     * as `afterTimeStep` in subsequent verifications to prevent replay attacks.
     *
     * @example Replay protection flow
     * ```typescript
     * // First verification
     * const result1 = await verify({ secret, token, crypto });
     * // result1 = { valid: true, delta: 0, timeStep: 41152263, epoch: 1234578900 }
     * await saveLastTimeStep(result1.timeStep);
     *
     * // Subsequent verification - rejects codes from time step 41152263 and earlier
     * const lastTimeStep = await getLastTimeStep();
     * const result2 = await verify({
     *   secret,
     *   token: newToken,
     *   crypto,
     *   afterTimeStep: lastTimeStep, // Reject timeStep <= 41152263
     * });
     * ```
     *
     * @example With epochTolerance
     * ```typescript
     * // Current time step: 41152263, window: 1
     * verify({
     *   secret,
     *   token,
     *   crypto,
     *   afterTimeStep: 41152262, // Rejects 41152262 and earlier
     *   epochTolerance: 30,       // Allows 41152263, 41152264 (within window)
     * });
     * ```
     */
    readonly afterTimeStep?: number;
};
/**
 * Successful verification result with delta offset
 */
type VerifyResultValid = {
    /** Token is valid */
    readonly valid: true;
    /**
     * The offset from the current time step where the token matched.
     * - 0: Token matched at current time step (no drift)
     * - Negative: Token matched in a past time step (client clock behind)
     * - Positive: Token matched in a future time step (client clock ahead)
     */
    readonly delta: number;
    /**
     * The exact epoch timestamp (in seconds) of the period start where the token matched.
     *
     * This provides the precise Unix timestamp for the beginning of the time period
     * in which the token was valid. Useful for logging, debugging, and advanced
     * time drift analysis.
     *
     * @example
     * ```typescript
     * const result = await verify({ secret, token, epochTolerance: 30 });
     * if (result.valid) {
     *   console.log(`Token matched at epoch: ${result.epoch}`);
     *   console.log(`Token was ${result.delta} periods away`);
     * }
     * ```
     */
    readonly epoch: number;
    /**
     * The time step number (per RFC 6238) used for verification.
     *
     * Per RFC 6238, time step T = floor((CurrentUnixTime - T0) / X), where X is the period.
     * This is the actual time step counter value, not a Unix timestamp.
     *
     * This value is always included in successful verifications and can be used for
     * replay attack prevention by passing it as `afterTimeStep` in subsequent verifications.
     *
     * @example Replay protection
     * ```typescript
     * const result = await verify({ secret, token, crypto });
     * if (result.valid) {
     *   // Save timeStep to prevent reuse
     *   await db.saveLastTimeStep(userId, result.timeStep);
     * }
     *
     * // Later: verify with replay protection
     * const lastTimeStep = await db.getLastTimeStep(userId);
     * const result2 = await verify({
     *   secret,
     *   token: newToken,
     *   crypto,
     *   afterTimeStep: lastTimeStep, // Rejects timeStep <= lastTimeStep
     * });
     * ```
     */
    readonly timeStep: number;
};
/**
 * Failed verification result
 */
type VerifyResultInvalid = {
    /** Token is invalid */
    readonly valid: false;
};
/**
 * Result of OTP verification (discriminated union)
 *
 * Use type narrowing to access `delta`:
 * ```ts
 * const result = await verify({ secret, token, epochTolerance: 30 });
 * if (result.valid) {
 *   // TypeScript knows delta exists here
 *   if (result.delta !== 0) {
 *     console.log(`Clock drift detected: ${result.delta} periods`);
 *   }
 *   console.log(`Token matched at epoch: ${result.epoch}`);
 * }
 * ```
 */
type VerifyResult = VerifyResultValid | VerifyResultInvalid;

/**
 * @otplib/totp
 *
 * TOTP class wrapper for convenient API
 */

/**
 * TOTP class for time-based one-time password generation
 *
 * @example
 * ```typescript
 * import { TOTP } from '@otplib/totp';
 * import { NodeCryptoPlugin } from '@otplib/plugin-crypto-node';
 * import { ScureBase32Plugin } from '@otplib/plugin-base32-scure';
 *
 * const totp = new TOTP({
 *   issuer: 'MyApp',
 *   label: 'user@example.com',
 *   crypto: new NodeCryptoPlugin(),
 *   base32: new ScureBase32Plugin(),
 * });
 *
 * const secret = totp.generateSecret();
 * const token = await totp.generate();
 * const isValid = await totp.verify(token);
 * ```
 */
declare class TOTP {
    private readonly options;
    private readonly guardrails;
    constructor(options?: TOTPOptions);
    /**
     * Generate a random Base32-encoded secret
     *
     * @returns Base32-encoded secret
     */
    generateSecret(): string;
    /**
     * Generate a TOTP code
     *
     * @param options - Optional overrides
     * @returns The TOTP code
     */
    generate(options?: Partial<TOTPOptions>): Promise<string>;
    /**
     * Verify a TOTP code
     *
     * @param token - The token to verify
     * @param options - Optional verification options
     * @returns Verification result with validity and optional delta
     */
    verify(token: string, options?: Partial<Omit<TOTPVerifyOptions, "token">>): Promise<VerifyResult>;
    /**
     * Generate an otpauth:// URI for QR codes
     *
     * When called with parameters, merges them with instance options.
     * This preserves algorithm, digits, and period settings from the instance
     * while allowing label, issuer, and secret to be overridden.
     *
     * @param options - Optional overrides for label, issuer, and secret
     * @returns The otpauth:// URI
     *
     * @example Without parameters (uses instance settings)
     * ```typescript
     * const totp = new TOTP({
     *   label: 'user@example.com',
     *   issuer: 'MyApp',
     *   secret: 'JBSWY3DPEHPK3PXP',
     *   crypto: new NodeCryptoPlugin(),
     *   base32: new ScureBase32Plugin(),
     * });
     * const uri = totp.toURI();
     * ```
     *
     * @example With parameters (overrides instance settings)
     * ```typescript
     * const totp = new TOTP({
     *   algorithm: 'sha256',
     *   digits: 8,
     *   crypto: new NodeCryptoPlugin(),
     *   base32: new ScureBase32Plugin(),
     * });
     * // Uses instance's algorithm and digits with provided label/issuer/secret
     * const uri = totp.toURI({
     *   label: 'user@example.com',
     *   issuer: 'MyApp',
     *   secret: 'JBSWY3DPEHPK3PXP',
     * });
     * ```
     */
    toURI(options?: {
        label?: string;
        issuer?: string;
        secret?: string;
    }): string;
}

/**
 * @otplib/totp
 *
 * RFC 6238 TOTP (Time-Based One-Time Password) implementation.
 *
 * TOTP extends HOTP (RFC 4226) by using time as the moving factor
 * instead of an event counter.
 *
 * @see {@link https://tools.ietf.org/html/rfc6238 | RFC 6238}
 * @see {@link https://tools.ietf.org/html/rfc4226 | RFC 4226 (HOTP base algorithm)}
 */

/**
 * Generate a Time-based One-Time Password (TOTP)
 *
 * Implements the TOTP algorithm as specified in RFC 6238 Section 4:
 *
 * ```
 * T = (Current Unix time - T0) / X
 * TOTP = HOTP(K, T)
 * ```
 *
 * Where:
 * - T0 is the Unix time to start counting time steps (default 0, per RFC 6238 Section 4.1)
 * - X is the time step in seconds (default 30, per RFC 6238 Section 4.1)
 * - K is the shared secret key
 *
 * @see {@link https://tools.ietf.org/html/rfc6238#section-4 | RFC 6238 Section 4 - TOTP Algorithm}
 * @see {@link https://tools.ietf.org/html/rfc6238#section-4.1 | RFC 6238 Section 4.1 - Parameters}
 *
 * @param options - TOTP generation options
 * @returns The TOTP code as a string
 *
 * @example
 * ```ts
 * import { generate } from '@otplib/totp';
 * import { NodeCryptoPlugin } from '@otplib/plugin-crypto-node';
 *
 * const totp = generate({
 *   secret: new Uint8Array([1, 2, 3, 4, 5]),
 *   time: Date.now() / 1000,
 *   period: 30,
 *   digits: 6,
 *   crypto: new NodeCryptoPlugin(),
 * });
 * // Returns: '123456'
 * ```
 */
declare function generate(options: TOTPGenerateOptions): Promise<string>;
/**
 * Generate a Time-based One-Time Password (TOTP) synchronously
 *
 * This is the synchronous version of {@link generate}. It requires a crypto
 * plugin that supports synchronous HMAC operations (e.g., NodeCryptoPlugin
 * or NobleCryptoPlugin). Using this with WebCryptoPlugin will throw an error.
 *
 * @see {@link generate} for the async version
 * @see {@link https://tools.ietf.org/html/rfc6238#section-4 | RFC 6238 Section 4}
 *
 * @param options - TOTP generation options
 * @returns The TOTP code as a string
 * @throws {HMACError} If the crypto plugin doesn't support sync operations
 *
 * @example
 * ```ts
 * import { generateSync } from '@otplib/totp';
 * import { NodeCryptoPlugin } from '@otplib/plugin-crypto-node';
 *
 * const totp = generateSync({
 *   secret: new Uint8Array([1, 2, 3, 4, 5]),
 *   epoch: Math.floor(Date.now() / 1000),
 *   period: 30,
 *   digits: 6,
 *   crypto: new NodeCryptoPlugin(),
 * });
 * // Returns: '123456'
 * ```
 */
declare function generateSync(options: TOTPGenerateOptions): string;
/**
 * Verify a TOTP code
 *
 * Compares the provided token against the expected TOTP value
 * using constant-time comparison to prevent timing attacks.
 *
 * The verification window allows for clock drift between client and server,
 * as recommended in RFC 6238 Section 5.2.
 *
 * @see {@link https://tools.ietf.org/html/rfc6238#section-5.2 | RFC 6238 Section 5.2 - Validation and Time-Step Size}
 *
 * @param options - TOTP verification options
 * @returns Verification result with validity and optional delta
 *
 * @example Using epochTolerance
 * ```ts
 * import { verify } from '@otplib/totp';
 * import { NodeCryptoPlugin } from '@otplib/plugin-crypto-node';
 *
 * // Accept tokens valid within ±30 seconds
 * const result = await verify({
 *   secret: mySecret,
 *   token: '123456',
 *   epochTolerance: 30,
 *   crypto: new NodeCryptoPlugin(),
 * });
 * if (result.valid) {
 *   console.log(`Token matched at epoch: ${result.epoch}`);
 * }
 * ```
 */
declare function verify(options: TOTPVerifyOptions): Promise<VerifyResult>;
/**
 * Verify a TOTP code synchronously
 *
 * This is the synchronous version of {@link verify}. It requires a crypto
 * plugin that supports synchronous HMAC operations (e.g., NodeCryptoPlugin
 * or NobleCryptoPlugin). Using this with WebCryptoPlugin will throw an error.
 *
 * @see {@link verify} for the async version
 * @see {@link https://tools.ietf.org/html/rfc6238#section-5.2 | RFC 6238 Section 5.2}
 *
 * @param options - TOTP verification options
 * @returns Verification result with validity and optional delta
 * @throws {HMACError} If the crypto plugin doesn't support sync operations
 *
 * @example
 * ```ts
 * import { verifySync } from '@otplib/totp';
 * import { NodeCryptoPlugin } from '@otplib/plugin-crypto-node';
 *
 * const result = verifySync({
 *   secret: mySecret,
 *   token: '123456',
 *   epochTolerance: 30,
 *   crypto: new NodeCryptoPlugin(),
 * });
 * if (result.valid) {
 *   console.log(`Token matched at epoch: ${result.epoch}`);
 * }
 * ```
 */
declare function verifySync(options: TOTPVerifyOptions): VerifyResult;
/**
 * Get the remaining time until the next TOTP period
 *
 * @param time - Current Unix timestamp in seconds (default: now)
 * @param period - Time step in seconds (default: 30)
 * @param t0 - Initial Unix time to start counting time steps (default: 0)
 * @returns Remaining seconds until next period
 *
 * @example
 * ```ts
 * import { getRemainingTime } from '@otplib/totp';
 *
 * const remaining = getRemainingTime();
 * // Returns: 15 (seconds remaining in current 30-second window)
 * ```
 */
declare function getRemainingTime(time?: number, period?: number, t0?: number, guardrails?: OTPGuardrails): number;
/**
 * Get the current TOTP counter value
 *
 * @param time - Current Unix timestamp in seconds (default: now)
 * @param period - Time step in seconds (default: 30)
 * @param t0 - Initial Unix time to start counting time steps (default: 0)
 * @returns Current counter value
 *
 * @example
 * ```ts
 * import { getTimeStepUsed } from '@otplib/totp';
 *
 * const counter = getTimeStepUsed();
 * // Returns: 12345 (current counter value)
 * ```
 */
declare function getTimeStepUsed(time?: number, period?: number, t0?: number, guardrails?: OTPGuardrails): number;

export { TOTP, type TOTPGenerateOptions, type TOTPOptions, type TOTPVerifyOptions, type VerifyResult, type VerifyResultInvalid, type VerifyResultValid, generate, generateSync, getRemainingTime, getTimeStepUsed, verify, verifySync };
