import { INotifier, NotificationAlign, NotificationCallProps, NotificationContent, NotificationReturn } from "@etsoo/notificationbase";
import { ApiDataError, IApi, IPData } from "@etsoo/restclient";
import { DataTypes, DateUtils, ErrorData, ErrorType, IActionResult, IStorage, ListType, ListType1 } from "@etsoo/shared";
import { AddressRegion } from "../address/AddressRegion";
import { EntityStatus } from "../business/EntityStatus";
import { InitCallDto } from "../api/dto/InitCallDto";
import { InitCallResult, InitCallResultData } from "../result/InitCallResult";
import { IUser } from "../state/User";
import { IAppSettings } from "./AppSettings";
import { AppLoginParams, AppTryLoginParams, FormatResultCustomCallback, IApp, IAppFields, IDetectIPCallback, NavigateOptions, RefreshTokenProps } from "./IApp";
import { UserRole } from "./UserRole";
import { ExternalEndpoint } from "./ExternalSettings";
import { ApiRefreshTokenDto } from "../api/dto/ApiRefreshTokenDto";
import { ApiRefreshTokenRQ } from "../api/rq/ApiRefreshTokenRQ";
import { AuthApi } from "../api/AuthApi";
type ApiRefreshTokenFunction = (api: IApi, rq: ApiRefreshTokenRQ) => Promise<[string, number] | undefined>;
type ApiTaskData = [IApi, number, number, ApiRefreshTokenFunction, string?];
/**
 * Core application interface
 */
export interface ICoreApp<U extends IUser, S extends IAppSettings, N, C extends NotificationCallProps> extends IApp {
    /**
     * Settings
     */
    readonly settings: S;
    /**
     * Notifier
     */
    readonly notifier: INotifier<N, C>;
    /**
     * User data
     */
    userData?: U;
}
/**
 * Core application
 */
export declare abstract class CoreApp<U extends IUser, S extends IAppSettings, N, C extends NotificationCallProps> implements ICoreApp<U, S, N, C> {
    /**
     * Settings
     */
    readonly settings: S;
    /**
     * Default region
     */
    readonly defaultRegion: AddressRegion;
    /**
     * Fields
     */
    readonly fields: IAppFields;
    /**
     * API, not recommend to use it directly in code, wrap to separate methods
     */
    readonly api: IApi;
    /**
     * Application name
     */
    readonly name: string;
    /**
     * Notifier
     */
    readonly notifier: INotifier<N, C>;
    /**
     * Storage
     */
    readonly storage: IStorage;
    /**
     * Pending actions
     */
    readonly pendings: (() => any)[];
    /**
     * Debug mode
     */
    readonly debug: boolean;
    private _culture;
    /**
     * Culture, like zh-CN
     */
    get culture(): string;
    private _currency;
    /**
     * Currency, like USD for US dollar
     */
    get currency(): "AUD" | "CAD" | "CNY" | "EUR" | "GBP" | "HKD" | "JPY" | "NZD" | "SGD" | "USD";
    private _region;
    /**
     * Country or region, like CN
     */
    get region(): string;
    private _deviceId;
    /**
     * Device id, randome string from ServiceBase.InitCallAsync
     */
    get deviceId(): string;
    protected set deviceId(value: string);
    /**
     * Label delegate
     */
    get labelDelegate(): <T = string>(key: string) => T | undefined;
    private _ipData?;
    /**
     * IP data
     */
    get ipData(): IPData | undefined;
    protected set ipData(value: IPData | undefined);
    private _userData?;
    /**
     * User data
     */
    get userData(): U | undefined;
    protected set userData(value: U | undefined);
    private ipDetectCallbacks?;
    /**
     * Search input element
     */
    searchInput?: HTMLInputElement;
    private _authorized;
    /**
     * Is current authorized
     */
    get authorized(): boolean;
    private set authorized(value);
    private _isReady;
    /**
     * Is the app ready
     */
    get isReady(): boolean;
    private set isReady(value);
    /**
     * Current cached URL
     */
    get cachedUrl(): string | undefined | null;
    set cachedUrl(value: string | undefined | null);
    /**
     * Keep login or not
     */
    get keepLogin(): boolean;
    set keepLogin(value: boolean);
    private _embedded;
    /**
     * Is embedded
     */
    get embedded(): boolean;
    private _isTryingLogin;
    /**
     * Is trying login
     */
    get isTryingLogin(): boolean;
    protected set isTryingLogin(value: boolean);
    /**
     * Get core API name
     */
    protected get coreName(): string;
    /**
     * Last called with token refresh
     */
    protected lastCalled: boolean;
    /**
     * Init call Api URL
     */
    protected initCallApi: string;
    /**
     * Passphrase for encryption
     */
    protected passphrase: string;
    private apis;
    private tasks;
    private clearInterval?;
    /**
     * Get persisted fields
     */
    protected readonly persistedFields: string[];
    /**
     * Protected constructor
     * @param settings Settings
     * @param api API
     * @param notifier Notifier
     * @param storage Storage
     * @param name Application name
     * @param debug Debug mode
     */
    protected constructor(settings: S, api: IApi | undefined | null, notifier: INotifier<N, C>, storage: IStorage, name: string, debug?: boolean);
    /**
     * Format settings
     * @param settings Original settings
     * @returns Result
     */
    protected formatSettings(settings: S): S;
    private getDeviceId;
    private resetKeys;
    /**
     * Add app name as identifier
     * @param field Field
     * @returns Result
     */
    protected addIdentifier(field: string): string;
    /**
     * Add root (homepage) to the URL
     * @param url URL to add
     * @returns Result
     */
    addRootUrl(url: string): string;
    /**
     * Check current app is in same session
     * @param callback Callback
     */
    checkSession(callback: (isSame: boolean) => Promise<void | false>): Promise<void>;
    /**
     * Clear user session
     */
    clearSession(): void;
    /**
     * Create Auth API
     * @param api Specify the API to use
     * @returns Result
     */
    protected createAuthApi(api?: IApi): AuthApi;
    /**
     * Restore settings from persisted source
     */
    protected restore(): Promise<boolean>;
    /**
     * Dispose the application
     */
    dispose(): void;
    /**
     * Is valid password, override to implement custom check
     * @param password Input password
     */
    isValidPassword(password: string): boolean;
    /**
     * Persist settings to source when application exit
     */
    persist(): void;
    /**
     * Add scheduled task
     * @param task Task, return false to stop
     * @param seconds Interval in seconds
     */
    addTask(task: () => PromiseLike<void | false>, seconds: number): void;
    /**
     * Create API client, override to implement custom client creation by name
     * @param name Client name
     * @param item External endpoint item
     * @returns Result
     */
    createApi(name: string, item: ExternalEndpoint, refresh?: (api: IApi, rq: ApiRefreshTokenRQ) => Promise<[string, number] | undefined>): IApi<any>;
    /**
     * Reset all APIs
     */
    protected resetApis(): void;
    /**
     * Update API token and expires
     * @param name Api name
     * @param token Refresh token
     * @param seconds Access token expires in seconds
     */
    updateApi(name: string, token: string | undefined, seconds: number): void;
    updateApi(data: ApiTaskData, token: string | undefined, seconds: number): void;
    /**
     * Setup Api
     * @param api Api
     */
    protected setApi(api: IApi, refresh?: ApiRefreshTokenFunction): void;
    /**
     * Setup Api error handler
     * @param api Api
     * @param handlerFor401 Handler for 401 error
     */
    setApiErrorHandler(api: IApi, handlerFor401?: boolean | (() => Promise<void>)): void;
    /**
     * Setup Api loading
     * @param api Api
     */
    setApiLoading(api: IApi): void;
    /**
     * Setup frontend logging
     * @param action Custom action
     * @param preventDefault Is prevent default action
     */
    setupLogging(action?: (data: ErrorData) => void | Promise<void>, preventDefault?: ((type: ErrorType) => boolean) | boolean): void;
    /**
     * Api init call
     * @param data Data
     * @returns Result
     */
    protected apiInitCall(data: InitCallDto): Promise<InitCallResult | undefined>;
    /**
     * Check the action result is about device invalid
     * @param result Action result
     * @returns true means device is invalid
     */
    checkDeviceResult(result: IActionResult): boolean;
    /**
     * Clear device id
     */
    clearDeviceId(): void;
    /**
     * Init call
     * @param callback Callback
     * @param resetKeys Reset all keys first
     * @returns Result
     */
    initCall(callback?: (result: boolean) => void, resetKeys?: boolean): Promise<void>;
    /**
     * Update passphrase
     * @param passphrase Secret passphrase
     */
    protected updatePassphrase(passphrase: string): void;
    /**
     * Init call update
     * @param data Result data
     * @param timestamp Timestamp
     */
    protected initCallUpdate(data: InitCallResultData, timestamp: number): Promise<boolean>;
    /**
     * Init call encrypted fields update
     * @returns Fields
     */
    protected initCallEncryptedUpdateFields(): string[];
    /**
     * Alert result
     * @param result Result message
     * @param callback Callback
     */
    alertResult(result: string, callback?: NotificationReturn<void>): void;
    /**
     * Alert action result
     * @param result Action result
     * @param callback Callback
     * @param forceToLocal Force to local labels
     */
    alertResult(result: IActionResult, callback?: NotificationReturn<void>, forceToLocal?: FormatResultCustomCallback): void;
    /**
     * Authorize
     * @param token New access token
     * @param schema Access token schema
     * @param refreshToken Refresh token
     */
    authorize(token?: string, schema?: string, refreshToken?: string): void;
    /**
     * On authorized or not callback
     * @param success Success or not
     */
    protected onAuthorized(success: boolean): void;
    /**
     * Change country or region
     * @param regionId New country or region
     */
    changeRegion(region: string | AddressRegion): void;
    /**
     * Change culture
     * @param culture New culture definition
     * @param onReady On ready callback
     */
    changeCulture(culture: DataTypes.CultureDefinition): Promise<DataTypes.StringRecord>;
    /**
     * Update current region label
     */
    protected updateRegionLabel(): void;
    /**
     * Check language is supported or not, return a valid language when supported
     * @param language Language
     * @returns Result
     */
    checkLanguage(language?: string): string;
    /**
     * Clear cache data
     */
    clearCacheData(): void;
    /**
     * Clear cached token
     */
    clearCacheToken(): void;
    /**
     * Decrypt message
     * @param messageEncrypted Encrypted message
     * @param passphrase Secret passphrase
     * @returns Pure text
     */
    decrypt(messageEncrypted: string, passphrase?: string): string | undefined;
    /**
     * Enhanced decrypt message
     * @param messageEncrypted Encrypted message
     * @param passphrase Secret passphrase
     * @param durationSeconds Duration seconds, <= 12 will be considered as month
     * @returns Pure text
     */
    decryptEnhanced(messageEncrypted: string, passphrase?: string, durationSeconds?: number): string | undefined;
    /**
     * Detect IP data, call only one time
     * @param callback Callback will be called when the IP is ready
     */
    detectIP(callback?: IDetectIPCallback): void;
    private detectIPCallbacks;
    /**
     * Download file
     * @param stream File stream
     * @param filename File name
     * @param callback callback
     */
    download(stream: ReadableStream, filename?: string, callback?: (success: boolean | undefined) => void): Promise<void>;
    /**
     * Encrypt message
     * @param message Message
     * @param passphrase Secret passphrase
     * @param iterations Iterations, 1000 times, 1 - 99
     * @returns Result
     */
    encrypt(message: string, passphrase?: string, iterations?: number): string;
    /**
     * Enhanced encrypt message
     * @param message Message
     * @param passphrase Secret passphrase
     * @param iterations Iterations, 1000 times, 1 - 99
     * @returns Result
     */
    encryptEnhanced(message: string, passphrase?: string, iterations?: number): string;
    /**
     * Enchance secret passphrase
     * @param passphrase Secret passphrase
     * @param timestamp Timestamp
     * @returns Enhanced passphrase
     */
    protected encryptionEnhance(passphrase: string, timestamp: string): string;
    /**
     * Format action
     * @param action Action
     * @param target Target name or title
     * @param items More items
     * @returns Result
     */
    formatAction(action: string, target: string, ...items: string[]): string;
    /**
     * Format date to string
     * @param input Input date
     * @param options Options
     * @param timeZone Time zone
     * @returns string
     */
    formatDate(input?: Date | string, options?: DateUtils.FormatOptions, timeZone?: string): string | undefined;
    /**
     * Format money number
     * @param input Input money number
     * @param isInteger Is integer
     * @param options Options
     * @returns Result
     */
    formatMoney(input: number | bigint, isInteger?: boolean, options?: Intl.NumberFormatOptions): string;
    /**
     * Format number
     * @param input Input number
     * @param options Options
     * @returns Result
     */
    formatNumber(input: number | bigint, options?: Intl.NumberFormatOptions): string;
    /**
     * Format error
     * @param error Error
     * @returns Error message
     */
    formatError(error: ApiDataError): string;
    /**
     * Format as full name
     * @param familyName Family name
     * @param givenName Given name
     */
    formatFullName(familyName: string | undefined | null, givenName: string | undefined | null): string;
    private getFieldLabel;
    /**
     * Format result text
     * @param result Action result
     * @param forceToLocal Force to local labels
     */
    formatResult(result: IActionResult, forceToLocal?: FormatResultCustomCallback): string;
    /**
     * Get culture resource
     * @param key key
     * @returns Resource
     */
    get<T = string>(key: string): T | undefined;
    /**
     * Get multiple culture labels
     * @param keys Keys
     */
    getLabels<T extends string>(...keys: T[]): {
        [K in T]: string;
    };
    /**
     * Get bool items
     * @returns Bool items
     */
    getBools(): ListType1[];
    /**
     * Get cached token
     * @returns Cached token
     */
    getCacheToken(): string | undefined;
    /**
     * Get data privacies
     * @returns Result
     */
    getDataPrivacies(): ListType[];
    /**
     * Get enum item number id list
     * @param em Enum
     * @param prefix Label prefix or callback
     * @param filter Filter
     * @returns List
     */
    getEnumList<E extends DataTypes.EnumBase = DataTypes.EnumBase>(em: E, prefix: string | ((key: string) => string), filter?: ((id: E[keyof E], key: keyof E & string) => E[keyof E] | undefined) | E[keyof E][]): ListType[];
    /**
     * Get enum item string id list
     * @param em Enum
     * @param prefix Label prefix or callback
     * @param filter Filter
     * @returns List
     */
    getEnumStrList<E extends DataTypes.EnumBase = DataTypes.EnumBase>(em: E, prefix: string | ((key: string) => string), filter?: (id: E[keyof E], key: keyof E & string) => E[keyof E] | undefined): ListType1[];
    /**
     * Get region label
     * @param id Region id
     * @returns Label
     */
    getRegionLabel(id: string): string;
    /**
     * Get all regions
     * @returns Regions
     */
    getRegions(): AddressRegion[];
    /**
     * Get role label
     * @param role Role value
     * @param joinChar Join char
     * @returns Label(s)
     */
    getRoleLabel(role: number | null | undefined, joinChar?: string): string;
    /**
     * Get roles
     * @param role Combination role value, null for all roles
     */
    getRoles(role?: number): ListType[];
    /**
     * Get status list
     * @param ids Limited ids
     * @returns list
     */
    getStatusList(ids?: EntityStatus[]): ListType[];
    /**
     * Get status label
     * @param status Status value
     */
    getStatusLabel(status: number | null | undefined): string;
    /**
     * Get refresh token from response headers
     * @param rawResponse Raw response from API call
     * @param tokenKey Refresh token key
     * @returns response refresh token
     */
    getResponseToken(rawResponse: any, tokenKey: string): string | null;
    /**
     * Get time zone
     * @returns Time zone
     */
    getTimeZone(): string;
    /**
     * Hash message, SHA3 or HmacSHA512, 512 as Base64
     * https://cryptojs.gitbook.io/docs/
     * @param message Message
     * @param passphrase Secret passphrase
     */
    hash(message: string, passphrase?: string): string;
    /**
     * Hash message Hex, SHA3 or HmacSHA512, 512 as Base64
     * https://cryptojs.gitbook.io/docs/
     * @param message Message
     * @param passphrase Secret passphrase
     */
    hashHex(message: string, passphrase?: string): string;
    /**
     * Check user has the minimum role permission or not
     * @param role Minumum role
     * @returns Result
     */
    hasMinPermission(role: UserRole): boolean;
    /**
     * Check user has the specific role permission or not
     * @param roles Roles to check
     * @returns Result
     */
    hasPermission(roles: number | UserRole | number[] | UserRole[]): boolean;
    /**
     * Is admin user
     * @returns Result
     */
    isAdminUser(): boolean;
    /**
     * Is Finance user
     * @returns Result
     */
    isFinanceUser(): boolean;
    /**
     * Is Manager user
     * @returns Result
     */
    isManagerUser(): boolean;
    /**
     * Load URL
     * @param url URL
     * @param targetOrigin Target origin
     */
    loadUrl(url: string, targetOrigin?: string): void;
    /**
     * Navigate to Url or delta
     * @param url Url or delta
     * @param options Options
     */
    navigate<T extends number | string | URL>(to: T, options?: T extends number ? never : NavigateOptions): void;
    /**
     * Notify user with success message
     * @param callback Popup close callback
     * @param message Success message
     */
    ok(callback?: NotificationReturn<void>, message?: NotificationContent<N>): void;
    /**
     * Callback where exit a page
     */
    pageExit(): void;
    /**
     * Fresh countdown UI
     * @param callback Callback
     */
    abstract freshCountdownUI(callback?: () => PromiseLike<unknown>): void;
    /**
     * Refresh token
     * @param props Props
     * @param callback Callback
     */
    refreshToken(props?: RefreshTokenProps, callback?: (result?: boolean | IActionResult) => boolean | void): Promise<void>;
    /**
     * Refresh token with success
     * @param user User data
     * @param token Refresh token
     * @param callback Callback
     */
    protected refreshTokenSucceed(user: U, token: string, callback?: (result?: boolean | IActionResult) => boolean | void): Promise<void>;
    /**
     * Setup callback
     */
    setup(): void;
    /**
     * Exchange token data
     * @param api API
     * @param token Core system's refresh token to exchange
     * @returns Result
     */
    exchangeToken(api: IApi, token: string): Promise<void>;
    /**
     * Exchange token update, override to get the new token
     * @param api API
     * @param data API refresh token data
     */
    protected exchangeTokenUpdate(api: IApi, data: ApiRefreshTokenDto): void;
    /**
     * Exchange intergration tokens for all APIs
     * @param coreData Core system's token data to exchange
     */
    exchangeTokenAll(coreData: ApiRefreshTokenDto): void;
    /**
     * API refresh token data
     * @param api Current API
     * @param rq Request data
     * @returns Result
     */
    protected apiRefreshTokenData(api: IApi, rq: ApiRefreshTokenRQ): Promise<ApiRefreshTokenDto | undefined>;
    /**
     * API refresh token
     * @param api Current API
     * @param rq Request data
     * @returns Result
     */
    protected apiRefreshToken(api: IApi, rq: ApiRefreshTokenRQ): Promise<[string, number] | undefined>;
    /**
     * Save refresh token to cache
     * @param token Refresh token
     */
    saveCacheToken(token: string | undefined): void;
    /**
     * Setup tasks
     */
    protected setupTasks(): void;
    /**
     * Signout, with userLogout and toLoginPage
     * @param action Callback
     */
    signout(action?: () => void | boolean): Promise<void>;
    /**
     * Go to the login page
     * @param data Login parameters
     */
    toLoginPage(data?: AppLoginParams): void;
    /**
     * Try login, returning false means is loading
     * UI get involved while refreshToken not intended
     * @param data Login parameters
     */
    tryLogin(data?: AppTryLoginParams): Promise<boolean>;
    /**
     * Update embedded status
     * @param embedded New embedded status
     * @param isWeb Is web or not
     */
    updateEmbedded(embedded: boolean | undefined | null, isWeb?: boolean): void;
    /**
     * User login
     * @param user User data
     * @param refreshToken Refresh token
     */
    userLogin(user: U, refreshToken: string): void;
    /**
     * User logout
     * @param clearToken Clear refresh token or not
     * @param noTrigger No trigger for state change
     */
    userLogout(clearToken?: boolean, noTrigger?: boolean): void;
    /**
     * User unauthorized
     */
    userUnauthorized(): void;
    private lastWarning?;
    /**
     * Show warning message
     * @param message Message
     * @param align Align, default as TopRight
     */
    warning(message: NotificationContent<N>, align?: NotificationAlign): void;
}
export {};
