import type { UseTranslationOptions as UseI18NextTranslationOptions } from "react-i18next";
import i18n, { TOptions } from "i18next";
import { ReactElement, ReactNode } from "react";
import { TransProps as TransI18nNextProps } from "react-i18next";
import type { DefaultSupportedLanguages } from "./translationServices.types.js";
/** A record of translation keys and their corresponding translated strings. */
export type I18nTranslationBundle = Record<string, string>;
/** A record of language codes and their corresponding translation bundles. */
export type ResourcesRecord = Record<string, I18nTranslationBundle>;
/**
 * Props for the `getTranslationServices` function.
 * It infers the supported language codes and bundle types from the `resources` object.
 */
export type GetTranslationServicesProps<TNamespace extends string, TResources extends ResourcesRecord, TDefaultLanguageCode extends Extract<keyof TResources, string>> = {
    /**
     * Default language code to fall back to.
     * MUST be one of the keys in the `resources` object.
     */
    defaultLanguageCode: TDefaultLanguageCode;
    /** The namespace for the translation resources. */
    namespace: TNamespace;
    /** The resources object, from which all language codes and bundle types are inferred. */
    resources: TResources;
};
export type TranslationOverrides<SupportedLanguageCodes extends string = DefaultSupportedLanguages> = Record<SupportedLanguageCodes, Partial<I18nTranslationBundle>>;
export type TranslationProviderProps<SupportedLanguageCodes extends string = DefaultSupportedLanguages> = {
    children: ReactNode;
    languageCode?: SupportedLanguageCodes;
    translationOverrides?: TranslationOverrides<SupportedLanguageCodes>;
};
type ExtractPlaceholders<TString extends string> = TString extends `${string}{{${infer PlaceholderId}}}${infer Rest}` ? PlaceholderId | ExtractPlaceholders<Rest> : never;
export type PlaceholderValues = string | number | TemplateStringsArray | (string | TemplateStringsArray)[];
export type PlaceholderRecord<TResourceBundle extends I18nTranslationBundle, TKey extends keyof TResourceBundle & string> = Record<ExtractPlaceholders<TResourceBundle[TKey]>, PlaceholderValues>;
/**
 * Custom function signature that enforces strong typing
 * against the keys of a specific resource bundle.
 */
export type TypedTFunction<TResourceBundle extends I18nTranslationBundle> = <TKey extends keyof TResourceBundle & string>(...args: [ExtractPlaceholders<TResourceBundle[TKey]>] extends [never] ? [
    key: TKey | TKey[],
    options?: TOptions
] : [
    key: TKey | TKey[],
    options: TOptions<PlaceholderRecord<TResourceBundle, TKey>>
]) => string;
/**
 * Return type of our strongly-typed `useTranslation` hook.
 *
 * Matches the original `useTranslation` return type, but with
 * our `TypedTFunction` rather than the generic `TFunction`.
 */
export type TypedUseTranslationResponse<TResourceBundle extends I18nTranslationBundle> = [t: TypedTFunction<TResourceBundle>, i18n: typeof i18n, ready: boolean] & {
    i18n: typeof i18n;
    ready: boolean;
    t: TypedTFunction<TResourceBundle>;
};
export interface IGenericTranslationProvider {
    <SupportedLanguageCodes extends string = DefaultSupportedLanguages>(props: TranslationProviderProps<SupportedLanguageCodes>): ReactNode;
}
export type UseTranslationOptions<TNamespace extends string> = Omit<UseI18NextTranslationOptions<TNamespace>, "i18n">;
/**
 * A strongly-typed version of the `useTranslation` hook from `react-i18next`,
 * bound to a specific namespace and resource bundle type.
 */
export type UseTranslation<TNamespace extends string, TResourceBundle extends I18nTranslationBundle> = (options?: UseTranslationOptions<TNamespace>) => TypedUseTranslationResponse<TResourceBundle>;
export type TypedTrans<TNamespace extends string, TResourceBundle extends I18nTranslationBundle> = <TKey extends Extract<keyof TResourceBundle, string>>(props: Omit<TransI18nNextProps<TKey & string, TNamespace>, "i18n" | "values" | "i18nKey"> & {
    i18nKey: TKey | TKey[];
} & ([ExtractPlaceholders<TResourceBundle[TKey]>] extends [never] ? {
    values?: never;
} : {
    values: PlaceholderRecord<TResourceBundle, TKey>;
})) => ReactElement;
export type TranslationServices<TNamespace extends string, TResources extends ResourcesRecord, TDefaultLanguageCode extends Extract<keyof TResources, string>> = {
    /** The i18next instance created for this package. */
    i18n: typeof i18n;
    Trans: TypedTrans<TNamespace, TResources[TDefaultLanguageCode]>;
    /**
     * A ready-to-use Translation Provider, which is a generic component.
     *
     * The consumer can specify the supported languages when using it.
     * @example <TranslationProvider<"en" | "ja">>
     */
    TranslationProvider: IGenericTranslationProvider;
    /** A pre-typed `useTranslation` hook bound to the given namespace. */
    useTranslation: UseTranslation<TNamespace, TResources[TDefaultLanguageCode]>;
};
/**
 * Initializes an `i18next` instance and provides strongly-typed
 * translation utilities: `useTranslation`, `Trans`, and `TranslationProvider`.
 */
export declare function getTranslationServices<TNamespace extends string, TResources extends ResourcesRecord, TDefaultLanguageCode extends Extract<keyof TResources, string>>({ defaultLanguageCode, namespace, resources, }: GetTranslationServicesProps<TNamespace, TResources, TDefaultLanguageCode>): TranslationServices<TNamespace, TResources, TDefaultLanguageCode>;
export {};
