import { IObservable, IObservableCallback } from "../observable";
import { Dict, I18n as I18nJs, I18nOptions, Scope, TranslateOptions } from "i18n-js";
import { LocaleSpecification } from "moment";
import "reflect-metadata";
import { I18nEvent, II18nTranslation } from "../types/i18n";
import { IDict } from "../types/index";
/**
* A decorator to attach metadata to properties or methods for translation.
* @param key The translation key in the translations.
* @returns A property and method decorator.
* @example
* ```ts
*   // Class with translations using the decorator
    class MyComponent {
        @Translate("greeting")
        public greeting: string;

        @Translate("nested.example")
        public nestedExample: string;

        @Translate("farewell")
        public sayGoodbye(): string {
            return "";
        }
    }
* ```
*/
export declare function Translate(key: string): PropertyDecorator & MethodDecorator;
/**
 * The I18n class extends the i18n-js library to provide internationalization (i18n)
 * functionality with observable capabilities. It manages translations, allows for
 * dynamic loading of language dictionaries, and supports event-driven architecture
 * through observable patterns.
 *
 * @extends I18nJs
 * @implements IObservable<I18nEvent>
 *
 * @example
 * // Example usage of the I18n class
 * const i18nInstance = I18n.getInstance();
 * i18nInstance.registerTranslations({
 *   en: {
 *     greeting: "Hello, {name}!",
 *     farewell: "Goodbye!",
 *   },
 * });
 * console.log(i18nInstance.translate("greeting", { name: "John" })); // Outputs: Hello, John!
 * @see https://www.npmjs.com/package/i18n-js?activeTab=readme for more information on i18n-js library.
 */
export declare class I18n extends I18nJs implements IObservable<I18nEvent> {
    /**
     * Custom instanceof check. When consumers import `I18n` from built packages or
     * across module boundaries, class identity can differ. Using Symbol.hasInstance
     * allows `instanceof I18n` to succeed if the object has the required i18n API
     * shape (duck typing). This preserves `instanceof` checks externally while
     * keeping the current exported API intact.
     */
    static [Symbol.hasInstance](obj: any): obj is I18n;
    /**
     * Type guard to check if an object is an instance of I18n.
     * Uses duck typing to verify the object has the required i18n methods,
     * allowing for cross-realm compatibility when instanceof checks fail.
     * @param obj The object to check.
     * @returns True if the object is an I18n instance, false otherwise.
     */
    static isI18nInstance(obj: any): obj is I18n;
    /**
     * Translates the given scope with the provided options.
     * If the scope is a string and the options include pluralization, the method will pluralize the translation.
     * Otherwise, it will call the parent `translate` method.
     * @param scope The translation scope.
     * @param options The translation options, including pluralization.
     * @returns The translated string or the type specified in the generic parameter.
     * @example
     * // Register translations for the "en" locale.
     * i18n.registerTranslations({
     *   en: {
     *     greeting: {
     *       one: "Hello, %{name}!",
     *       other: "Hello, %{name}s!",
     *       zero: "Hello, %{name}s!"
     *     },
     *     farewell: "Goodbye!"
     *   }
     * });
     *
     * // Translate the "greeting" scope with pluralization.
     * i18n.translate("greeting", { count: 1 }); // "Hello, John!"
     * i18n.translate("greeting", { count: 2 }); // "Hello, Johns!"
     * i18n.translate("greeting", { count: 0 }); // "Hello, Johns!"
     *
     * // Translate the "farewell" scope.
     * i18n.translate("farewell"); // "Goodbye!"
     */
    translate<T = string>(scope: Scope, options?: TranslateOptions): string | T;
    /***
     * Translates the keys of the given target class.
     * @param target The target class.
     * @param options The translation options.
     * @returns The translated keys.
     */
    translateTarget<T extends {
        new (...args: any[]): {};
    } = any>(target: T, options?: TranslateOptions): Record<keyof T, string>;
    /**
     * Translates an object containing translation keys as values.
     * This method takes an object where each property value is expected to be a translation key,
     * and returns a new object with the same structure but with translated values.
     *
     * @template T - The type of the input object, extending Record<string, string>
     * @param object - The object containing translation keys as values to be translated
     * @param {TranslateOptions} options - additional options to pass to the i18n.translate function
     * @returns A new object with the same keys but translated values
     *
     * @example
     * ```typescript
     * // Register translations first
     * i18n.registerTranslations({
     *   en: {
     *     'user.name': 'Name',
     *     'user.email': 'Email Address',
     *     'user.phone': 'Phone Number',
     *     'actions.save': 'Save',
     *     'actions.cancel': 'Cancel'
     *   },
     *   fr: {
     *     'user.name': 'Nom',
     *     'user.email': 'Adresse Email',
     *     'user.phone': 'Numéro de Téléphone',
     *     'actions.save': 'Enregistrer',
     *     'actions.cancel': 'Annuler'
     *   }
     * });
     *
     * // Define an object with translation keys
     * const formLabels = {
     *   name: 'user.name',
     *   email: 'user.email',
     *   phone: 'user.phone'
     * };
     *
     * // Translate the object
     * const translatedLabels = i18n.translateObject(formLabels);
     * console.log(translatedLabels);
     * // Output (for 'en' locale): { name: 'Name', email: 'Email Address', phone: 'Phone Number' }
     * // Output (for 'fr' locale): { name: 'Nom', email: 'Adresse Email', phone: 'Numéro de Téléphone' }
     *
     * // Can also be used with button configurations
     * const buttonConfig = {
     *   saveButton: 'actions.save',
     *   cancelButton: 'actions.cancel'
     * };
     * const translatedButtons = i18n.translateObject(buttonConfig);
     * // Output (for 'en' locale): { saveButton: 'Save', cancelButton: 'Cancel' }
     * ```
     *
     * @example
     * ```typescript
     * // Advanced usage with form validation messages
     * const validationMessages = {
     *   required: 'validation.required',
     *   email: 'validation.email.invalid',
     *   minLength: 'validation.minLength',
     *   maxLength: 'validation.maxLength'
     * };
     *
     * // Assuming you have registered validation translations
     * const translatedValidation = i18n.translateObject(validationMessages);
     * // This allows you to easily get all validation messages in the current locale
     * ```
     *
     * @note If the input object is not a valid object, an empty object of type T is returned.
     * @note Only string values that are non-null and non-empty are translated; other values are skipped.
     * @note This method is particularly useful for translating configuration objects, form labels,
     *       button texts, or any structured data containing translation keys.
     *
     * @see {@link translateTarget} for translating class properties decorated with @Translate
     * @see {@link t} for translating individual keys with interpolation support
     *
     * @since 1.20.3
     */
    translateObject<T extends Record<string, string> = any>(object: T, options?: TranslateOptions): T;
    /***
     * returns the translation keys for the target class
     * @param target the target class
     * @returns the translation keys for the target class
     */
    static getTargetTanslationKeys<T extends {
        new (...args: any[]): {};
    } = any>(target: T): Record<keyof T, string>;
    private _isLoading;
    /***
     * locales that are superted by the i18n instance
     */
    private _locales;
    /**
     * Namespace resolvers for loading translations.
     */
    private namespaceResolvers;
    /**
     * Singleton instance of the I18n class.
     */
    private static instance;
    /**
     * Creates an instance of the I18n class.
     * @param options Optional configuration options for the I18n instance.
     */
    constructor(translations?: II18nTranslation, options?: Partial<I18nOptions>);
    readonly _observableFactory: {
        _____isObservable?: boolean;
        on: (event: I18nEvent, fn: IObservableCallback) => {
            remove: () => any;
        };
        finally: (event: I18nEvent, fn: IObservableCallback) => /*elided*/ any;
        off: (event: I18nEvent, fn: IObservableCallback) => /*elided*/ any;
        trigger: (event: "*" | I18nEvent, ...args: any[]) => /*elided*/ any;
        offAll: () => /*elided*/ any;
        once: (event: I18nEvent, fn: IObservableCallback) => {
            remove: () => any;
        };
        getEventCallBacks: () => Partial<Record<"*" | I18nEvent, IObservableCallback[]>>;
    };
    readonly _____isObservable?: boolean | undefined;
    /**
     * Subscribes a callback function to a specific event.
     * @param event The event name to listen for.
     * @param fn The callback function to be invoked when the event is triggered.
     * @returns An object containing a remove method to unsubscribe from the event.
     */
    on(event: I18nEvent, fn: IObservableCallback): {
        remove: () => any;
    };
    /**
     * Registers a callback to be invoked finally when an event is triggered.
     * @param event The event name.
     * @param fn The callback function to be invoked.
     * @returns The observable instance.
     */
    finally(event: I18nEvent, fn: IObservableCallback): {
        _____isObservable?: boolean;
        on: (event: I18nEvent, fn: IObservableCallback) => {
            remove: () => any;
        };
        finally: (event: I18nEvent, fn: IObservableCallback) => /*elided*/ any;
        off: (event: I18nEvent, fn: IObservableCallback) => /*elided*/ any;
        trigger: (event: "*" | I18nEvent, ...args: any[]) => /*elided*/ any;
        offAll: () => /*elided*/ any;
        once: (event: I18nEvent, fn: IObservableCallback) => {
            remove: () => any;
        };
        getEventCallBacks: () => Partial<Record<"*" | I18nEvent, IObservableCallback[]>>;
    };
    /**
     * Unsubscribes a callback from a specific event.
     * @param event The event name.
     * @param fn The callback function to remove.
     * @returns The observable instance.
     */
    off(event: I18nEvent, fn: IObservableCallback): {
        _____isObservable?: boolean;
        on: (event: I18nEvent, fn: IObservableCallback) => {
            remove: () => any;
        };
        finally: (event: I18nEvent, fn: IObservableCallback) => /*elided*/ any;
        off: (event: I18nEvent, fn: IObservableCallback) => /*elided*/ any;
        trigger: (event: "*" | I18nEvent, ...args: any[]) => /*elided*/ any;
        offAll: () => /*elided*/ any;
        once: (event: I18nEvent, fn: IObservableCallback) => {
            remove: () => any;
        };
        getEventCallBacks: () => Partial<Record<"*" | I18nEvent, IObservableCallback[]>>;
    };
    /**
     * Triggers a specific event with optional arguments.
     * @param event The event name to trigger.
     * @param args Optional arguments to pass to the event callbacks.
     * @returns The observable instance.
     */
    trigger(event: I18nEvent | "*", ...args: any[]): {
        _____isObservable?: boolean;
        on: (event: I18nEvent, fn: IObservableCallback) => {
            remove: () => any;
        };
        finally: (event: I18nEvent, fn: IObservableCallback) => /*elided*/ any;
        off: (event: I18nEvent, fn: IObservableCallback) => /*elided*/ any;
        trigger: (event: "*" | I18nEvent, ...args: any[]) => /*elided*/ any;
        offAll: () => /*elided*/ any;
        once: (event: I18nEvent, fn: IObservableCallback) => {
            remove: () => any;
        };
        getEventCallBacks: () => Partial<Record<"*" | I18nEvent, IObservableCallback[]>>;
    };
    /**
     * Unsubscribes all event callbacks for this component.
     * @returns The observable instance.
     */
    offAll(): IObservable<I18nEvent>;
    /**
     * Subscribes a callback function to be triggered once for a specific event.
     * @param event The event name.
     * @param fn The callback function to be invoked.
     * @returns An object containing a remove method to unsubscribe from the event.
     */
    once(event: I18nEvent, fn: IObservableCallback): {
        remove: () => any;
    };
    /**
     * Retrieves all registered event callbacks.
     * @returns An object mapping event names to their respective callback functions.
     */
    getEventCallBacks(): Partial<Record<"*" | I18nEvent, IObservableCallback[]>>;
    /**
     * Retrieves the singleton instance of the I18n class.
     * @returns The singleton I18n instance.
     */
    static getInstance(options?: I18nOptions): I18n;
    /***
     * returns true if the instance is the default instance.
     * @returns true if the instance is the default instance.
     */
    isDefaultInstance(): boolean;
    private static setLocaleToSession;
    static getLocaleFromSession(): any;
    /**
     * Checks if the provided translation key can be pluralized for the given locale.
     * @param scope The translation scope to check.
     * @param locale The locale to use for the check. If not provided, the current locale is used.
     * @returns `true` if the translation key can be pluralized, `false` otherwise.
     * @note This method is useful for determining if a translation key can be pluralized for a specific locale.
     * A translation key can be pluralized if it has pluralization rules defined in the translation dictionary.
     * The pluralization rules are defined in the `one`, `other`, and `zero` properties of the translation dictionary.
     * @example
     * //register a translation dictionary for the "en" locale.
     * i18n.registerTranslations({
     *   en: {
     *     greeting: {
     *       one: "Hello, {name}!",
     *       other: "Hello, {name}s!",
     *       zero: "Hello, {name}s!"
     *     },
     *     farewell: "Goodbye!"
     *   }
     * );
     * });
     * // Check if the translation key "greeting" can be pluralized for the current locale.
     * i18n.canPluralize("greeting");
     *
     * // Check if the translation key "greeting" can be pluralized for the "en" locale.
     * i18n.canPluralize("greeting", "en");
     * i18n.canPluralize("greeting", "fr"); // returns false
     * i18n.canPluralize("farewell", "en"); // returns false
     */
    canPluralize(scope: Scope, locale?: string): boolean;
    /**
     * Resolves translation for nested keys.
     * @param scope {Scope} The translation scope.
     * @param locale The locale to use for translation.
     * @returns The translated string or undefined if not found.
     * @example
     * // Register translations for the "en" locale.
     * i18n.registerTranslations({
     *   en: {
     *     greeting: {
     *       one: "Hello, {name}!",
     *       other: "Hello, {name}s!",
     *       zero: "Hello, {name}s!"
     *     },
     *     farewell: "Goodbye!"
     *   }
     * });
     *
     * // Resolve translation for the "greeting" key.
     * i18n.getNestedTranslation("greeting.one", "en");
     *
     * // Resolve translation for the "greeting" key.
     * i18n.getNestedTranslation("greeting.other", "en");
     *
     * // Resolve translation for the "greeting" key.
     * i18n.getNestedTranslation("en", "greeting.zero", 0);
     *
     * // Resolve translation for the "farewell" key.
     * i18n.getNestedTranslation("en", "farewell");
     */
    getNestedTranslation(scope: Scope, locale?: string): string | IDict | undefined;
    /**
     * Checks if the provided `TranslateOptions` object has a `count` property of type `number`.
     * This is used to determine if the translation should be pluralized based on the provided count.
     * @param options The `TranslateOptions` object to check.
     * @returns `true` if the `options` object has a `count` property of type `number`, `false` otherwise.
     */
    isPluralizeOptions(options?: TranslateOptions): options is TranslateOptions;
    /**
       * static function to attach translations to the I18n default instance.
          @example :
          // --- Usage as a decorator ---
          I18n.RegisterTranslations({
              de: {
                  greeting: "Hallo, {name}!",
                  farewell: "Auf Wiedersehen!",
              },
          })
      * @param translations The language translations.
      */
    static RegisterTranslations(translations: II18nTranslation): II18nTranslation;
    /**
     * Factory method to create I18n instances dynamically.
     * @param options Optional configuration options for the I18n instance.
     * @returns A new I18n instance.
     */
    static createInstance(translations?: II18nTranslation, options?: Partial<I18nOptions> & {
        interpolate?: (i18n: I18nJs, str: string, params: Record<string, any>) => string;
    }): I18n;
    /**
     * Gets the translations for the specified locale, or all translations if no locale is provided.
     * @param locale The locale to get translations for. If not provided, returns all translations.
     * @returns The translations for the specified locale, or all translations if no locale is provided.
     * @example
     * // Get all translations
     * const translations = i18n.getTranslations();
     * console.log(translations);
     *
     * // Get translations for the "en" locale
     * const enTranslations = i18n.getTranslations("en");
     * console.log(enTranslations);
     */
    getTranslations(locale?: string): any;
    /***
     * list of registered moment locales
     */
    private static momentLocales;
    /***
     * register a moment locale
     * @param {string} locale
     * @param {LocaleSpecification} momentLocale
     * @see https://momentjs.com/docs/#/customization/ for more information on customizing moment locales
     * @see https://momentjs.com/docs/#/i18n/ for more information on moment locales
     * @returns
     */
    static registerMomentLocale(locale: string, momentLocale: LocaleSpecification): Record<string, LocaleSpecification>;
    /***
     * get a registered moment locale
     * @param {string} locale
     * @returns {LocaleSpecification}
     */
    static getMomentLocale(locale: string): LocaleSpecification;
    /***
     * set a moment locale. the locale is picked from the momentLocales list
     * @param {string} locale
     * @param {Moment} momentInstance, The moment instance to set the locale on
     * @returns {boolean}
     */
    static setMomentLocale(locale: string): boolean;
    /**
     * Registers translations into the I18n manager.
     * @param translations The translations to register.
     * @returns The updated translations.
     */
    registerTranslations(translations: II18nTranslation): II18nTranslation;
    /**
     * Stores the provided translations and triggers a "translations-changed" event with the current locale and translations.
     * @param translations The translations to store.
     */
    store(translations: Dict): void;
    /**
     * Automatically resolves translations using reflect Metadata.
     * Translations created using the @Translate decorator will be resolved.
     * @param target The target class instance or object.
     * @example
     * // Class with translations using the decorator
     * class MyComponent {
     *     @Translate("greeting")
     *     public greeting: string;
     *
     *     @Translate("nested.example")
     *     public nestedExample: string;
     *
     *     @Translate("farewell")
     *     public sayGoodbye(): string {
     *         return "";
     *     }
     * }
     * // Resolve translations and print them
     * const component = new MyComponent();
     * I18n.getInstance().resolveTranslations(component);
     */
    resolveTranslations<T extends Object>(target: T): void;
    /***
     * returns the missing placeholder string for the given placeholder and message.
     * @param placeholder - The placeholder to be replaced.
     * @param message - The message to be displayed.
     * @param options - The options for the missing placeholder string.
     * @returns The missing placeholder string.
     */
    getMissingPlaceholderString(placeholder: string, message?: string, options?: II18nTranslation): string;
    /**
     * Gets the current locale for the i18n instance.
     * @returns {string} The current locale.
     */
    getLocale(): string;
    /**
     * Sets the list of supported locales for the i18n instance.
     * @param locales - An array of locale strings to set as the supported locales.
     * @returns The list of all locales supported by the i18n instance, including both the locales for which translations are available and the locales explicitly set as supported.
     */
    setLocales(locales: string[]): string[];
    /***
     * returns true if the locale is supported by a i18n instance.
     * @param locale - The locale to check.
     * @returns true if the locale is supported, false otherwise.
     */
    hasLocale(locale: string): boolean;
    /**
     * Gets the list of all locales supported by the i18n instance, including both the locales for which translations are available and the locales explicitly set as supported.
     * @returns {string[]} The list of all supported locales.
     */
    getLocales(): string[];
    /***
     * returns true if the locale is supported by the i18n instance.
     * @param locale - The locale to check.
     * @returns true if the locale is supported, false otherwise.
     */
    isLocaleSupported(locale: string): boolean;
    /***
     * returns true if the instance is loading translations.
     * @returns true if the instance is loading translations, false otherwise.
     * @example
     * // Check if the instance is loading translations.
     * i18n.isLoading();
     */
    isLoading(): boolean;
    private _namespacesLoaded;
    setLocale(locale: string, forceUpdate?: boolean): Promise<string>;
    /**
     * Register a namespace resolver.
     * @param namespace The namespace to register.
     * @param resolver The resolver function to load the namespace.
     * @example
     * // Register a namespace resolver for the "common" namespace.
     * i18n.registerNamespaceResolver("common", async (locale) => {
     *   const response = await fetch(`/i18n/${locale}/common.json`);
     *   return await response.json();
     * });
     */
    registerNamespaceResolver(namespace: string, resolver: (locale: string) => Promise<II18nTranslation>): void;
    /**
     * Static method to register a namespace resolver to the I18n default instance.
     * @param namespace, The namespace to register.
     * @param resolver, The resolver function to load the namespace.
     * @returns
     * @example
     * // Register a namespace resolver for the "common" namespace.
     * I18n.RegisterNamespaceResolver("common", async (locale) => {
     *   const response = await fetch(`/i18n/${locale}/common.json`);
     *   return await response.json();
     * });
     */
    static RegisterNamespaceResolver(namespace: string, resolver: (locale: string) => Promise<any>): void;
    loadNamespace(namespace: string, locale?: string, updateTranslations?: boolean): Promise<II18nTranslation>;
    static LoadNamespace(namespace: string, locale?: string, updateTranslations?: boolean): Promise<II18nTranslation>;
    loadNamespaces(locale?: string, updateTranslations?: boolean): Promise<II18nTranslation>;
    /***
     * Load all registered namespaces for the current locale on the I18n default instance.
     * @param locale optional locale to load the namespaces for
     * @param updateTranslations optional boolean to update the translations
     * @returns {Promise<II18nTranslation>} A promise that resolves to the combined translations for the current local
     */
    static LoadNamespaces(locale?: string, updateTranslations?: boolean): Promise<II18nTranslation>;
    static flattenObject(obj: any): TranslateOptions;
    /**
     * Provides a default interpolation function for the I18n instance.
     *
     * If the input `value` is `undefined` or `null`, an empty string is returned.
     * If the input `value` is not a number, boolean, or string, it is converted to a string using `stringify`.
     * If the input `params` is not an object, the `value` is returned as-is.
     * If the input `params` is an object, the `value` is replaced with any matching placeholders in the format `%{key}` using the corresponding values from the `params` object.
     *
     * @param i18n The I18n instance.
     * @param value The input value to be interpolated.
     * @param params Optional object containing replacement values for placeholders in the `value`.
     * @returns The interpolated string.
     */
    private static defaultInterpolator;
}
declare const i18n: I18n;
export { i18n };
