import { BaseLMSAction } from '../../base/base-lms.action.js';
import { UserInfo } from '@memberjunction/core';
import { ActionParam } from '@memberjunction/actions-base';
import { LWApiEnrollmentStatus, LWApiProgressData, LearnWorldsUser } from './interfaces/index.js';
/**
 * Base class for all LearnWorlds LMS actions.
 * Handles LearnWorlds-specific authentication and API interaction patterns.
 */
export declare abstract class LearnWorldsBaseAction extends BaseLMSAction {
    protected lmsProvider: string;
    protected integrationName: string;
    /**
     * LearnWorlds API version
     */
    protected apiVersion: string;
    /**
     * Concurrency limit for parallel API calls to avoid overwhelming the API.
     */
    protected static readonly CONCURRENCY_LIMIT = 5;
    /**
     * Allowed user roles in LearnWorlds.
     */
    protected static readonly ALLOWED_ROLES: readonly string[];
    /**
     * Maximum number of items per page supported by the LearnWorlds API
     */
    protected static readonly LW_MAX_PAGE_SIZE = 100;
    private static readonly MAX_RETRIES;
    private static readonly BASE_DELAY_MS;
    private static readonly MAX_DELAY_MS;
    private static readonly RATE_LIMIT_WINDOW_MS;
    private static readonly RATE_LIMIT_MAX_REQUESTS;
    private static readonly INTER_BATCH_DELAY_MS;
    /**
     * Safety limit for pagination to prevent infinite loops if the API misbehaves.
     */
    protected static readonly MAX_PAGES = 100;
    /**
     * Sliding-window timestamps shared across all instances so concurrent
     * actions against the same LearnWorlds school stay within the limit.
     */
    private static requestTimestamps;
    /**
     * Reset the global rate-limiter state. Intended for test teardown only.
     */
    static ResetRateLimiter(): void;
    /**
     * Current action parameters (set by the framework or by SetCompanyContext)
     */
    protected params: ActionParam[];
    /**
     * Tracks the number of actual HTTP requests made since last reset.
     * Useful for callers that need accurate API call counts (e.g., bulk data).
     */
    protected apiCallCount: number;
    /**
     * Public accessor for the running API call count.
     */
    get ApiCallCount(): number;
    /**
     * Set the company context for direct (non-framework) calls.
     * This populates `this.params` so that `makeLearnWorldsRequest` can find the CompanyID.
     */
    SetCompanyContext(companyId: string): void;
    /**
     * Makes an authenticated request to LearnWorlds API.
     * The body parameter accepts any object that will be JSON-serialized.
     */
    protected makeLearnWorldsRequest<T = Record<string, unknown>>(endpoint: string, method?: 'GET' | 'POST' | 'PUT' | 'DELETE', body?: object | null, contextUser?: UserInfo): Promise<T>;
    /**
     * Resolves integration credentials and builds the base URL and headers.
     */
    private buildRequestConfig;
    /**
     * Makes an authenticated request to a non-versioned LearnWorlds API endpoint (e.g. /admin/api/sso).
     */
    protected makeLearnWorldsNonVersionedRequest<T = Record<string, unknown>>(endpoint: string, method?: 'GET' | 'POST' | 'PUT' | 'DELETE', body?: object | null, contextUser?: UserInfo): Promise<T>;
    /**
     * Parses error details from a non-OK API response.
     */
    private buildErrorMessage;
    /**
     * Makes a paginated request to LearnWorlds API
     */
    protected makeLearnWorldsPaginatedRequest<T = Record<string, unknown>>(endpoint: string, queryParams?: Record<string, string | number | boolean>, contextUser?: UserInfo, maxResults?: number): Promise<T[]>;
    /**
     * Convert LearnWorlds date format to Date object
     */
    protected parseLearnWorldsDate(dateString: string | number): Date;
    /**
     * Format date for LearnWorlds API (ISO 8601)
     */
    protected formatLearnWorldsDate(date: Date): string;
    /**
     * Map LearnWorlds user status to standard status
     */
    protected mapUserStatus(status: string): 'active' | 'inactive' | 'suspended';
    /**
     * Map LearnWorlds enrollment status
     */
    protected mapLearnWorldsEnrollmentStatus(enrollment: LWApiEnrollmentStatus): 'active' | 'completed' | 'expired' | 'suspended';
    /**
     * Calculate progress from LearnWorlds data
     */
    protected calculateProgress(progressData: LWApiProgressData): {
        percentage: number;
        completedUnits: number;
        totalUnits: number;
        timeSpent: number;
    };
    /**
     * Safely parses a date string to ISO format.
     * Returns undefined if the input is falsy or produces an invalid date.
     */
    protected safeParseDateToISO(dateString: string | undefined): string | undefined;
    /**
     * Validates that a value is safe to use as a URL path segment.
     * Rejects values containing path traversal or URL manipulation characters.
     */
    protected validatePathSegment(value: string, paramName: string): string;
    /**
     * Validates that a school domain is safe to use in URL construction.
     * Must look like a hostname (alphanumeric + hyphens + dots).
     */
    private validateSchoolDomain;
    /**
     * Validates that a role is in the allowed set.
     */
    protected validateRole(role: string): string;
    /**
     * Validates that a string is a plausible email address.
     */
    protected validateEmail(email: string, paramName?: string): string;
    /**
     * Validates that a redirect URL is either a relative path or an absolute URL
     * that belongs to the LearnWorlds school domain and uses http(s).
     */
    protected validateRedirectTo(redirectTo: string, schoolDomain?: string): string;
    /**
     * Returns a promise that resolves after `ms` milliseconds.
     */
    private waitForRetryDelay;
    /**
     * Pure calculation — determines how long to wait before the next retry.
     * Prefers the Retry-After header (seconds → ms, capped); falls back to
     * exponential backoff with random jitter.
     */
    private calculateRetryDelay;
    /**
     * Proactive throttle: if the sliding window is at capacity, sleep until
     * the oldest request falls outside the window.
     */
    private waitForRateLimitCapacity;
    /**
     * Stamps the current time into the sliding window.
     */
    private recordRequest;
    /**
     * Wraps `fetch` with 429-aware retry + proactive rate-limit throttling.
     * Non-429 responses are returned immediately without retry.
     * If all retries are exhausted the final 429 response is returned (not thrown).
     */
    private sendRequestWithRetry;
    /**
     * Processes items in batches with controlled concurrency.
     * Prevents unbounded parallel API calls from overwhelming the target API.
     */
    protected processInBatches<TItem, TResult>(items: TItem[], processFn: (item: TItem) => Promise<TResult>, batchSize?: number): Promise<TResult[]>;
    /**
     * Gets a required string parameter, throwing if missing or empty.
     */
    protected getRequiredStringParam(params: ActionParam[], name: string): string;
    /**
     * Gets an optional string parameter.
     */
    protected getOptionalStringParam(params: ActionParam[], name: string): string | undefined;
    /**
     * Gets an optional boolean parameter with a default value.
     * When defaultValue is undefined, returns undefined if the parameter is missing.
     */
    protected getOptionalBooleanParam(params: ActionParam[], name: string, defaultValue: boolean): boolean;
    protected getOptionalBooleanParam(params: ActionParam[], name: string, defaultValue: boolean | undefined): boolean | undefined;
    /**
     * Gets an optional number parameter with a default value.
     * When defaultValue is undefined, returns undefined if the parameter is missing.
     */
    protected getOptionalNumberParam(params: ActionParam[], name: string, defaultValue: number): number;
    protected getOptionalNumberParam(params: ActionParam[], name: string, defaultValue: number | undefined): number | undefined;
    /**
     * Gets an optional string array parameter.
     */
    protected getOptionalStringArrayParam(params: ActionParam[], name: string): string[] | undefined;
    /**
     * Shared utility: find a LearnWorlds user by email.
     * Returns the user if found, null if not found (empty results).
     * Re-throws errors for network failures, auth errors, rate limiting, etc.
     */
    FindUserByEmail(email: string, contextUser: UserInfo): Promise<LearnWorldsUser | null>;
    /**
     * Maps a raw LW API user to the normalized LearnWorldsUser shape.
     */
    private mapLWApiUserToLearnWorldsUser;
}
//# sourceMappingURL=learnworlds-base.action.d.ts.map