import { HttpClient, HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpHandlerFn } from '@angular/common/http';
import { Observable } from 'rxjs';
import * as i0 from '@angular/core';

/**
 * Represents the authentication status of the principal.
 * Used to track the current state in OAuth flows.
 */
declare enum AlphaAuthStatusEnum {
    Undefined = 0,
    Anonymous = 1,
    Authenticating = 2,
    Refreshing = 3,
    Authenticated = 4
}
/**
 * Represents a user in the authentication system.
 * Contains identity, language, and custom properties.
 */
interface IAlphaUser {
    /** Unique identifier for the user. */
    userId: string;
    /** Username or display name. */
    username: string;
    /** Language code for localization. */
    languageCode: string;
    /** Custom user properties. */
    properties: Map<string, any>;
}
/**
 * Envelope containing authentication tokens and user information.
 * Used for exchanging authentication data between client and backend.
 */
interface IAlphaAuthEnvelop {
    /** Access token for API requests. */
    accessToken: string;
    /** Token expiry duration in seconds. */
    expiresIn: number;
    /** Refresh token for renewing access. */
    refreshToken: string;
    /** Authenticated user information. */
    user: IAlphaUser;
}
/**
 * Represents the principal (current authentication context).
 * Tracks status, user, language, and authentication flags.
 */
interface IAlphaPrincipal {
    /** Current authentication status. */
    status: AlphaAuthStatusEnum;
    /** Authenticated user or null if anonymous. */
    user: IAlphaUser | null;
    /** Session language code. */
    languageCode: string;
    /** True if authenticated. */
    isAuthenticated: boolean;
    /** True if anonymous. */
    isAnonymous: boolean;
    /** True if currently authenticating. */
    isAuthenticating: boolean;
    /** Sets the session language code. */
    setSessionLanguageCode(lc: string): void;
}

/**
 * AlphaOasService provides authentication and authorization logic for OAuth-based flows.
 * Handles sign-in, token refresh, user retrieval, and principal state management.
 *
 * Key Features:
 * - Supports custom implementations for sign-in, refresh, and authorize via injection methods.
 * - Manages session and refresh tokens using browser storage.
 * - Emits principal updates and error logs via callback functions.
 * - Designed for use as a singleton service (providedIn: 'root').
 *
 * Usage:
 * - Call `init()` to initialize the service with required URLs, HttpClient, and optional callbacks/storage.
 * - Use `signIn()`, `refresh()`, and `getMe()` for authentication flows.
 * - Use `authorize()` to wrap protected HTTP requests.
 * - Listen for principal updates via the `onPrincipalUpdated` callback.
 */
declare class AlphaOasService {
    /**
     * HttpClient instance for making HTTP requests. Set via init().
     */
    private mHttp;
    /**
     * Service context string for error logging.
     */
    private readonly mContext;
    /**
     * Principal representing the current authenticated user and status.
     */
    private readonly mPrincipal;
    /**
     * OAuth endpoint URLs. Set via init().
     */
    private mSignInUrl;
    private mRefreshUrl;
    private mGetMeUrl;
    /**
     * Storage objects for session and refresh tokens. Default to browser storage, can be injected.
     */
    private mSessionStorage;
    private mLocalStorage;
    /**
     * Callback for principal updates. Set via init().
     */
    private mOnPrincipalUpdated;
    /**
     * Callback for error logging. Set via init().
     */
    private mPostErrorLog;
    /**
     * Returns the current principal (user and status).
     */
    get principal(): IAlphaPrincipal;
    /**
     * Constructs the service and initializes the principal.
     */
    constructor();
    /**
     * Initializes the service with required dependencies and URLs.
     * Determines authentication state from session/refresh storage, or sets anonymous mode.
     *
     * @param httpClient - Angular HttpClient instance.
     * @param getMeUrl - URL for retrieving user info.
     * @param refreshUrl - URL for token refresh.
     * @param signInUrl - URL for sign-in.
     * @param postErrorLog - Optional error logging callback.
     * @param onPrincipalUpdated - Optional principal update callback.
     * @param sStorage - Optional session storage (default: browser sessionStorage).
     * @param lStorage - Optional local storage (default: browser localStorage).
     * @returns Observable emitting the result of initialization.
     */
    init(httpClient: HttpClient, getMeUrl?: string, refreshUrl?: string, signInUrl?: string, postErrorLog?: (context: string, method: string, error: string) => any, onPrincipalUpdated?: (principal: IAlphaPrincipal) => any, sStorage?: Storage, lStorage?: Storage): Observable<string>;
    /**
     * Sets the session and local storage objects used for token management.
     * @param sStorage - Session storage.
     * @param lStorage - Local storage.
     */
    initStorage(sStorage: Storage, lStorage: Storage): void;
    /**
     * Initializes authentication from session data (if present).
     * @returns Observable emitting result string.
     */
    private initFromSd;
    /**
     * Initializes authentication from refresh data (if present).
     * @returns Observable emitting result string.
     */
    private initFromRd;
    /**
     * Initializes authentication in anonymous mode (no session/refresh data).
     * @returns Observable emitting result string.
     */
    private initAsAnonymous;
    /**
     * Allows injection of a custom sign-in implementation.
     * @param signIn - Function implementing sign-in logic.
     */
    useSignIn(signIn: (userName: string, password: string, rememberMe: boolean) => Observable<IAlphaAuthEnvelop>): void;
    /**
     * Allows injection of a custom refresh implementation.
     * @param refresh - Function implementing refresh logic.
     */
    useRefresh(refresh: (refreshToken: string) => Observable<IAlphaAuthEnvelop>): void;
    /**
     * Allows injection of a custom authorize implementation.
     * @param authorize - Function implementing authorization logic.
     */
    useAuthorize(authorize: (request: Observable<any>) => Observable<any>): void;
    /**
     * Default sign-in implementation. Can be overridden via useSignIn().
     * @param username - User name.
     * @param password - User password.
     * @param rememberMe - Whether to persist refresh token.
     * @returns Observable emitting authentication envelope.
     */
    internalSignIn: (userName: string, password: string, rememberMe: boolean) => Observable<IAlphaAuthEnvelop>;
    /**
     * On successful login call storeIdentity.
     * Remark: there is no need to call getMe from signIn as getMe
     * is actually returning the same data as signIn
     * @param username
     * @param password
     * @param rememberMe
     */
    signIn(username: string, password: string, rememberMe: boolean): Observable<boolean>;
    /**
     * Default refresh implementation. Can be overridden via useRefresh().
     * @param refreshToken - Refresh token string.
     * @returns Observable emitting authentication envelope.
     */
    internalRefresh: (refreshToken: string) => Observable<IAlphaAuthEnvelop>;
    /**
     * Refreshes the access token using the refresh token from local storage.
     * Emits true on success, false on authentication error, or errors for other failures.
     * @returns Observable emitting boolean result.
     */
    refresh(): Observable<boolean>;
    /**
     * called from the init() method when the session data is present
     */
    getMe(): Observable<IAlphaUser>;
    /**
     * Edits the principal's user info and emits principal update.
     * @param firstName - New first name.
     * @param lastName - New last name.
     * @param languageCode - New language code.
     */
    editUserInfo(firstName: string, lastName: string, languageCode: string): void;
    /**
     * Signs out the user, clears tokens and principal, and emits principal update.
     */
    signOut(): void;
    /**
     * Default authorization implementation. Can be overridden via useAuthorize().
     * Checks token validity and refreshes if needed before firing request.
     * @param httpRequest - Observable HTTP request to authorize.
     * @returns Observable emitting the result of the request.
     */
    internalAuthorize(httpRequest: Observable<any>): Observable<any>;
    /**
     * Wraps a protected HTTP request with authorization logic.
     * @param httpRequest - Observable HTTP request to authorize.
     * @returns Observable emitting the result of the request.
     */
    authorize(httpRequest: Observable<any>): Observable<any>;
    /**
     * (1) stores the access token in the session storage
     * (2) stores the refresh token in the local storage
     * (3) populates the principal using the user info
     */
    storeIdentity(authEnvelop: IAlphaAuthEnvelop, rememberMe: boolean): void;
    /**
     * Populates the principal with user info and emits principal update.
     * @param user - User object.
     */
    private populatePrincipal;
    static ɵfac: i0.ɵɵFactoryDeclaration<AlphaOasService, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<AlphaOasService>;
}

/**
 * Factory for creating IAlphaUser instances from a raw data source object (DSO).
 * Converts backend user responses into strongly-typed user objects.
 *
 * Usage:
 * - Call `factorFromDso()` with a DSO to get an IAlphaUser instance.
 */
declare class AlphaUserFactory {
    /**
     * Converts a raw DSO into an IAlphaUser instance.
     * @param dso - The raw user data source object, typically from an API response.
     * @returns A strongly-typed user object implementing IAlphaUser.
     */
    static factorFromDso(dso: any): IAlphaUser;
}

/**
 * Factory class for creating authentication envelope instances from a raw data source object (DSO).
 * Provides a static method to convert backend authentication responses into a strongly-typed envelope.
 */
declare class AlphaAuthEnvelopFactory {
    /**
     * Converts a raw DSO into an IAlphaAuthEnvelop instance.
     * @param dso - The raw authentication data source object, typically from an API response.
     * @returns A strongly-typed authentication envelope implementing IAlphaAuthEnvelop.
     */
    static factorFromDso(dso: any): IAlphaAuthEnvelop;
}

/**
 * Represents the authentication principal for the current session.
 * Tracks authentication status, user identity, and session language.
 *
 * Responsibilities:
 * - Maintains the current authentication status (anonymous, authenticating, authenticated, etc.).
 * - Stores and manages the authenticated user object.
 * - Persists and retrieves the session language code for localization and HTTP header enrichment.
 * - Provides flags for authentication state (isAuthenticated, isAnonymous, isAuthenticating).
 * - Supports clearing user identity and session language on sign-out.
 *
 * Usage:
 * - Used by authentication services to manage and expose principal state.
 * - Interacts with browser sessionStorage for language code persistence.
 */
declare class AlphaPrincipal implements IAlphaPrincipal {
    /**
     * Current authentication status of the principal.
     */
    private mStatus;
    /**
     * Gets the current authentication status.
     */
    get status(): AlphaAuthStatusEnum;
    /**
     * Sets the authentication status.
     * @param status - New authentication status.
     */
    setStatus(status: AlphaAuthStatusEnum): void;
    /**
     * Current authenticated user, or null if anonymous.
     */
    private mUser;
    /**
     * Gets the current user object, or null if not authenticated.
     */
    get user(): IAlphaUser | null;
    /**
     * Sets the current user and updates the session language code.
     * @param user - Authenticated user object.
     */
    setUser(user: IAlphaUser): void;
    /**
     * Persists the session language code for localization and HTTP header enrichment.
     * @param lc - Language code to persist.
     */
    setSessionLanguageCode(lc: string): void;
    /**
     * Clears the user identity and removes the session language code from storage.
     */
    clearUser(): void;
    /**
     * Gets the current session language code.
     * Returns the user's language if authenticated, or falls back to sessionStorage or browser language.
     */
    get languageCode(): string;
    /**
     * True if the principal is authenticated.
     */
    get isAuthenticated(): boolean;
    /**
     * True if the principal is anonymous (not authenticated).
     */
    get isAnonymous(): boolean;
    /**
     * True if the principal is in the process of authenticating or refreshing.
     */
    get isAuthenticating(): boolean;
    /**
     * Constructs a new principal with undefined status and no user.
     */
    constructor();
}

/**
 * HTTP interceptor for OAuth authentication and client identification.
 *
 * Responsibilities:
 * - Adds language, client, and authorization headers to outgoing requests.
 * - Generates and persists a unique client ID per browser.
 * - Retrieves and attaches access tokens from session storage.
 * - Supports custom storage injection for testing or advanced scenarios.
 *
 * Usage:
 * - Use as a provider for HTTP_INTERCEPTORS in Angular.
 * - Call `initStorage()` to override default browser storage if needed.
 * - Use static `handlerFn()` for functional interceptors in Angular 16+.
 */
declare class AlphaOasInterceptor implements HttpInterceptor {
    /**
     * Session storage for language and access token. Defaults to browser sessionStorage.
     */
    private mSessionStorage;
    /**
     * Local storage for client ID. Defaults to browser localStorage.
     */
    private mLocalStorage;
    /**
     * Allows injection of custom storage objects for session and local storage.
     * Useful for testing or non-browser environments.
     * @param sStorage - Session storage object (default: browser sessionStorage).
     * @param lStorage - Local storage object (default: browser localStorage).
     */
    initStorage(sStorage?: Storage, lStorage?: Storage): void;
    /**
     * Intercepts outgoing HTTP requests and enriches them with authentication and client headers.
     * @param req - The outgoing HTTP request.
     * @param next - The next handler in the interceptor chain.
     * @returns Observable emitting the HTTP event stream.
     */
    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>;
    /**
     * Functional interceptor handler for Angular 16+.
     * Allows direct injection of storage for advanced scenarios or testing.
     * @param req - The outgoing HTTP request.
     * @param next - The next handler function.
     * @param sStorage - Session storage object (default: browser sessionStorage).
     * @param lStorage - Local storage object (default: browser localStorage).
     * @returns Observable emitting the HTTP event stream.
     */
    static handlerFn(req: HttpRequest<any>, next: HttpHandlerFn, sStorage?: Storage, lStorage?: Storage): Observable<HttpEvent<any>>;
    /**
     * Enriches an HTTP request with language, client, and authorization headers.
     * - Adds 'language-code' header based on session or browser language.
     * - Adds 'client-id' header, generating and persisting a UUID if needed.
     * - Adds 'authorization' header if an access token is present in session storage.
     * @param req - The original HTTP request.
     * @param sStorage - Session storage object.
     * @param lStorage - Local storage object.
     * @returns The enriched HTTP request.
     */
    private static enrichReq;
}

/**
 * Represents the session token data for OAuth authentication.
 *
 * Responsibilities:
 * - Stores, retrieves, and clears session token and metadata in browser storage.
 * - Tracks token reception and expiration timestamps for validity checks.
 * - Provides static methods for managing session token lifecycle.
 * - Used by authentication services to persist and access session tokens securely.
 *
 * Usage:
 * - Call `store()` to persist the session token and metadata in storage.
 * - Use `retrieve()` to get the session token and metadata from storage.
 * - Use `clear()` to remove the session token and metadata from storage on sign-out.
 * - Use `isExpiredOrExpiring` to check if the token is near expiration.
 * - Use `getTimestamps()` to calculate reception and expiration timestamps from expiry duration.
 */
declare class AlphaSessionData {
    /**
     * Storage key for the rememberMe flag.
     */
    private static readonly rememberMeFieldName;
    /**
     * Storage key for the access token.
     */
    private static readonly accessTokenFieldName;
    /**
     * Storage key for the token reception timestamp.
     */
    private static readonly receptionTsFieldName;
    /**
     * Storage key for the token expiration timestamp.
     */
    private static readonly expirationTsFieldName;
    /**
     * Indicates if the user chose "remember me" during authentication.
     */
    rememberMe: boolean;
    /**
     * The access token string.
     */
    accessToken: string;
    /**
     * Timestamp of token reception in milliseconds.
     */
    receptionTs: number;
    /**
     * Timestamp of token expiration in milliseconds.
     */
    expirationTs: number;
    /**
     * Returns true if the token is expired or will expire within 60 seconds.
     */
    get isExpiredOrExpiring(): boolean;
    /**
     * Constructs a new AlphaSessionData instance with the given properties.
     * @param rememberMe - Indicates if "remember me" was selected.
     * @param accessToken - The access token string.
     * @param receptionTs - Timestamp of token reception in ms.
     * @param expirationTs - Timestamp of token expiration in ms.
     */
    constructor(rememberMe: boolean, accessToken: string, receptionTs: number, // timestamp of token reception in ms
    expirationTs: number);
    /**
     * Calculates reception and expiration timestamps from expiry duration in seconds.
     * @param expiresIn - Expiry duration in seconds.
     * @returns Object containing receptionTs and expirationTs in ms.
     */
    static getTimestamps(expiresIn: number): {
        receptionTs: number;
        expirationTs: number;
    };
    /**
     * Retrieves the session data from storage and returns an AlphaSessionData instance.
     * @param mStorage - Storage object to use (default: browser sessionStorage).
     * @returns AlphaSessionData instance if data exists, otherwise null.
     */
    static retrieve(mStorage?: Storage): AlphaSessionData | null;
    /**
     * Removes the session data from storage.
     * @param mStorage - Storage object to use (default: browser sessionStorage).
     */
    static clear(mStorage?: Storage): void;
    /**
     * Stores the session data in storage.
     * @param mStorage - Storage object to use (default: browser sessionStorage).
     */
    store(mStorage?: Storage): void;
}

export { AlphaAuthEnvelopFactory, AlphaAuthStatusEnum, AlphaOasInterceptor, AlphaOasService, AlphaPrincipal, AlphaSessionData, AlphaUserFactory };
export type { IAlphaAuthEnvelop, IAlphaPrincipal, IAlphaUser };
