import { BaseEngine, IMetadataProvider, UserInfo } from '@memberjunction/core';
import { Observable } from 'rxjs';
import { MJApplicationSettingEntity } from '../generated/entity_subclasses.js';
/**
 * ApplicationSettingEngine is a singleton engine that provides centralized, cached access to
 * application configuration settings stored in the `MJ: Application Settings` entity
 * (table `ApplicationSetting`).
 *
 * Each setting row has an optional `ApplicationID`:
 * - **NULL** → a GLOBAL setting that applies across all applications.
 * - **non-NULL** → a setting scoped to that single application.
 *
 * **Resolution semantics**: when reading a setting for a given application, an app-scoped row
 * (matching applicationId + name) takes precedence over the GLOBAL row (ApplicationID NULL) of
 * the same name. If neither exists, the read returns `undefined`.
 *
 * This engine mirrors {@link UserInfoEngine}: it loads all setting rows into an in-memory cache
 * via a BaseEnginePropertyConfig (which auto-subscribes to BaseEntity events for reactivity),
 * exposes a reactive observable, and supports debounced writes with read-after-write semantics.
 *
 * Usage:
 * ```typescript
 * const engine = ApplicationSettingEngine.Instance;
 * await engine.Config(false, contextUser);
 *
 * // Read a setting (app-scoped first, then GLOBAL fallback)
 * const raw = engine.GetSetting('feature.flag', applicationId);
 *
 * // Write a GLOBAL setting
 * await engine.SetSetting('feature.flag', 'true');
 *
 * // Write an app-scoped setting
 * await engine.SetSetting('feature.flag', 'false', applicationId);
 * ```
 */
export declare class ApplicationSettingEngine extends BaseEngine<ApplicationSettingEngine> {
    /**
     * Returns the global instance of the class. This is a singleton class, so there is only one
     * instance of it in the application. Do not directly create new instances of it, always use
     * this method to get the instance.
     */
    static get Instance(): ApplicationSettingEngine;
    private _ApplicationSettings;
    /**
     * Debounce time in milliseconds for SetSettingDebounced calls.
     * Default is 500ms. Change via the SettingsDebounceMs setter.
     */
    private _settingsDebounceMs;
    /**
     * Map of pending setting updates keyed by `${applicationId}::${name}`.
     * These are queued and flushed after the debounce period of inactivity.
     */
    private _pendingSettings;
    /**
     * Timer handle for the debounce flush.
     */
    private _settingsDebounceTimer;
    /**
     * Promise that resolves when the current flush operation completes.
     * Used to prevent concurrent flush operations.
     */
    private _flushPromise;
    /**
     * Configures the engine by loading all application settings from the database into the
     * in-memory cache. Application settings are global reference data (not per-user), so all rows
     * are loaded regardless of provider type.
     *
     * @param forceRefresh - If true, forces a refresh from the server even if data is cached
     * @param contextUser - The user context (required for server-side)
     * @param provider - Optional custom metadata provider
     */
    Config(forceRefresh?: boolean, contextUser?: UserInfo, provider?: IMetadataProvider): Promise<void>;
    /**
     * Observable stream of the application settings cache array. Emits the current array on
     * subscribe and re-emits whenever the cache is mutated (save, delete, remote-invalidate,
     * refresh).
     */
    get ApplicationSettings$(): Observable<MJApplicationSettingEntity[]>;
    /**
     * Get all application settings in the cache (global + app-scoped, unfiltered).
     */
    get ApplicationSettings(): MJApplicationSettingEntity[];
    /**
     * Get all settings for a specific application, OR all GLOBAL settings when no applicationId
     * is supplied.
     *
     * @param applicationId - The application ID to filter by; omit/undefined for GLOBAL settings
     * @returns The matching settings (does NOT merge global fallbacks into the app-scoped list)
     */
    GetAllForApplication(applicationId?: string): MJApplicationSettingEntity[];
    /**
     * Get an application setting value by name with scope resolution.
     *
     * **Resolution**: if `applicationId` is given and an app-scoped row exists for
     * (applicationId, name), its value is returned. Otherwise the GLOBAL row (ApplicationID NULL)
     * for that name is used as a fallback. Returns `undefined` if neither exists.
     *
     * **Read-after-write semantics**: this consults the in-memory pending-debounced-writes map
     * FIRST (app-scoped pending takes precedence over global pending, mirroring the persisted
     * resolution order). Without that, a `SetSettingDebounced` followed immediately by
     * `GetSetting` would return the old DB-cached value because the debounce timer hasn't fired
     * yet and the entity hasn't been saved.
     *
     * @param name - The setting name to find
     * @param applicationId - Optional application scope; when given, app-scoped overrides global
     * @returns The setting value string, or undefined if not found
     */
    GetSetting(name: string, applicationId?: string): string | undefined;
    /**
     * Get an application setting entity by name with the same scope resolution as
     * {@link GetSetting} (app-scoped first, then GLOBAL fallback). Does NOT consult pending
     * debounced writes — returns the persisted entity instance.
     *
     * @param name - The setting name to find
     * @param applicationId - Optional application scope
     * @returns The MJApplicationSettingEntity, or undefined if not found
     */
    GetSettingEntity(name: string, applicationId?: string): MJApplicationSettingEntity | undefined;
    /**
     * Internal: find the cache row that exactly matches (name, scope) WITHOUT fallback.
     * A null/undefined applicationId matches only GLOBAL rows; a non-null applicationId matches
     * only the app-scoped row for that application.
     */
    private findEntity;
    /**
     * Set an application setting by name. Creates a new setting if one doesn't exist for the
     * exact (name, scope) pair; updates it otherwise. When `applicationId` is omitted the setting
     * is written as a GLOBAL setting (ApplicationID NULL).
     *
     * @param name - The setting name
     * @param value - The setting value (string, typically JSON for complex data)
     * @param applicationId - Optional application scope; omit for a GLOBAL setting
     * @param contextUser - Optional user context for server-side use
     * @returns true if successful, false otherwise
     */
    SetSetting(name: string, value: string, applicationId?: string, contextUser?: UserInfo): Promise<boolean>;
    /**
     * Delete an application setting by name and scope.
     *
     * @param name - The setting name to delete
     * @param applicationId - Optional application scope; omit to delete the GLOBAL setting
     * @returns true if successful (or setting didn't exist), false on error
     */
    DeleteSetting(name: string, applicationId?: string): Promise<boolean>;
    /**
     * Get the current debounce time in milliseconds for SetSettingDebounced calls.
     */
    get SettingsDebounceMs(): number;
    /**
     * Set the debounce time in milliseconds for SetSettingDebounced calls.
     * When changed, any pending settings are flushed first before the new debounce time takes effect.
     * @param value - The debounce time in milliseconds (minimum 100ms, maximum 10000ms)
     */
    set SettingsDebounceMs(value: number);
    /**
     * Queue a setting update with debouncing. Multiple calls within the debounce period for the
     * same (name, scope) pair are batched together, with only the last value being saved. The
     * actual database save occurs after the debounce period of inactivity.
     *
     * This is the preferred method for UI components that may update settings frequently.
     *
     * @param name - The setting name
     * @param value - The setting value (string, typically JSON for complex data)
     * @param applicationId - Optional application scope; omit for a GLOBAL setting
     * @param contextUser - Optional user context for server-side use
     */
    SetSettingDebounced(name: string, value: string, applicationId?: string, contextUser?: UserInfo): void;
    /**
     * Immediately flush all pending debounced settings to the database.
     * Call this when you need to ensure settings are saved (e.g., before navigation).
     * Safe to call multiple times - concurrent calls will wait for the current flush to complete.
     *
     * @returns Promise that resolves when all pending settings have been saved
     */
    FlushPendingSettings(): Promise<void>;
    /**
     * Internal method to perform the actual flush of settings.
     * @param settingsToSave - Map of settings to save
     */
    private doFlushSettings;
    /**
     * Check if there are any pending debounced settings waiting to be saved.
     */
    get HasPendingSettings(): boolean;
    /**
     * Get the number of pending debounced settings.
     */
    get PendingSettingsCount(): number;
    /**
     * Force refresh all application setting data.
     * @param contextUser - Optional user context for server-side use
     */
    Refresh(contextUser?: UserInfo): Promise<void>;
}
//# sourceMappingURL=ApplicationSettingEngine.d.ts.map