import { InjectionToken, makeEnvironmentProviders, provideEnvironmentInitializer, inject, provideAppInitializer } from '@angular/core';
import { ZCacheService, ZIndexDbService, Z_THEME_CONFIG, Z_LANG_CACHE_KEY } from '@shival99/z-ui/services';
import { provideEnvironmentNgxMask } from 'ngx-mask';
import { provideScrollbarOptions } from 'ngx-scrollbar';
import { HttpClient } from '@angular/common/http';
import { TranslateService, provideTranslateService, TranslateLoader } from '@ngx-translate/core';
import { of, from, forkJoin, map, firstValueFrom } from 'rxjs';
import { catchError } from 'rxjs/operators';

/** Injection token for ZCacheService configuration */
const Z_CACHE_CONFIG = new InjectionToken('Z_CACHE_CONFIG');
/**
 * Provide Z-Cache service with configuration
 * @param config - Cache configuration with prefix and encrypt options
 *
 * @example
 * ```typescript
 * // In app.config.ts
 * export const appConfig: ApplicationConfig = {
 *   providers: [
 *     provideZCache({
 *       prefix: 'myapp_',
 *       encrypt: false, // Disable encryption for debugging
 *     }),
 *   ],
 * };
 * ```
 */
function provideZCache(config = {}) {
    return makeEnvironmentProviders([
        {
            provide: Z_CACHE_CONFIG,
            useValue: config,
        },
        provideEnvironmentInitializer(() => {
            const cacheConfig = inject(Z_CACHE_CONFIG);
            ZCacheService.configure(cacheConfig);
        }),
    ]);
}

/** Injection token for ZIndexDbService */
const Z_INDEXDB_SERVICE = new InjectionToken('ZIndexDbService');
/**
 * Provide Z-IndexDB service with configuration
 * @param config - IndexDB configuration with multi-store support
 *
 * @example
 * ```typescript
 * // In app.config.ts
 * export const appConfig: ApplicationConfig = {
 *   providers: [
 *     provideZIndexDb({
 *       dbName: 'MyApp',
 *       version: 1,
 *       stores: [
 *         { name: 'cache', encrypt: true },
 *         { name: 'userData', encrypt: true, protectedKeys: ['profile'] },
 *         { name: 'settings', encrypt: false },
 *       ],
 *       defaultStore: 'cache',
 *       protectedKeys: ['token'],
 *     }),
 *   ],
 * };
 * ```
 */
function provideZIndexDb(config = {}) {
    return makeEnvironmentProviders([
        {
            provide: Z_INDEXDB_SERVICE,
            useFactory: () => new ZIndexDbService(config),
        },
        {
            provide: ZIndexDbService,
            useExisting: Z_INDEXDB_SERVICE,
        },
    ]);
}

const LANG_CACHE_KEY = 'Z_LANGUAGE';
/**
 * Get locale-specific mask configuration
 */
function getMaskConfig(lang, config = {}) {
    const isVietnamese = lang === 'vi';
    return {
        validation: config.validation ?? true,
        thousandSeparator: isVietnamese ? ',' : '.',
        decimalMarker: (isVietnamese ? '.' : ','),
        allowNegativeNumbers: config.allowNegativeNumbers ?? true,
    };
}
/**
 * Provide Z-NgxMask with locale-aware configuration
 * @param config - Mask configuration
 *
 * @example
 * ```typescript
 * // In app.config.ts
 * export const appConfig: ApplicationConfig = {
 *   providers: [
 *     provideZNgxMask({ lang: 'vi' }),
 *   ],
 * };
 * ```
 */
function provideZNgxMask(config = {}) {
    const savedLang = typeof window !== 'undefined' ? ZCacheService.get(LANG_CACHE_KEY) : null;
    const lang = config.lang ?? savedLang ?? 'vi';
    const maskConfig = getMaskConfig(lang, config);
    return makeEnvironmentProviders([provideEnvironmentNgxMask(maskConfig)]);
}

/**
 * Provides global scrollbar options for ngx-scrollbar
 * Use this in app.config.ts: providers: [provideZScrollbar()]
 */
function provideZScrollbar() {
    return makeEnvironmentProviders([
        provideScrollbarOptions({
            visibility: 'hover',
            appearance: 'compact',
            withButtons: false,
            sensorThrottleTime: 200,
        }),
    ]);
}

/**
 * Provide theme configuration for the application
 * @param config - Theme configuration with defaultTheme, defaultDarkMode, and optional cacheKey
 * @example
 * ```typescript
 * // In app.config.ts
 * export const appConfig: ApplicationConfig = {
 *   providers: [
 *     provideZTheme({
 *       defaultTheme: 'hospital',
 *       defaultDarkMode: false,
 *       cacheKey: 'Z_THEME_PREFERENCES_CRM',
 *     })
 *   ]
 * };
 * ```
 */
function provideZTheme(config = {}) {
    return makeEnvironmentProviders([{ provide: Z_THEME_CONFIG, useValue: config }]);
}

/* eslint-disable @stylistic/indent */
const DEFAULT_LANG = 'en';
const zuiTranslationsPromiseCache = new Map();
async function zLoadDefaultZUITranslations(lang) {
    const module = await import('@shival99/z-ui/i18n');
    return module.getZUITranslations(lang) ?? module.getZUITranslations(DEFAULT_LANG);
}
class ZTranslateHttpLoader {
    _http;
    _prefix;
    _suffix;
    _includeZUI;
    _zuiOverridePath;
    _zuiLoader;
    constructor(_http, _prefix, _suffix, _includeZUI, _zuiOverridePath, _zuiLoader = zLoadDefaultZUITranslations) {
        this._http = _http;
        this._prefix = _prefix;
        this._suffix = _suffix;
        this._includeZUI = _includeZUI;
        this._zuiOverridePath = _zuiOverridePath;
        this._zuiLoader = _zuiLoader;
    }
    _loadZUITranslations(lang) {
        const cached = zuiTranslationsPromiseCache.get(lang);
        if (cached) {
            return cached;
        }
        const loadPromise = this._zuiLoader(lang).catch(async () => {
            if (lang === DEFAULT_LANG) {
                return {};
            }
            return this._zuiLoader(DEFAULT_LANG).catch(() => ({}));
        });
        zuiTranslationsPromiseCache.set(lang, loadPromise);
        return loadPromise;
    }
    getTranslation(lang) {
        const userTranslations$ = this._http
            .get(`${this._prefix}${lang}${this._suffix}`)
            .pipe(catchError(() => of({})));
        if (!this._includeZUI) {
            return userTranslations$;
        }
        const zuiDefaults$ = from(this._loadZUITranslations(lang)).pipe(catchError(() => of({})));
        const zuiFileOverrides$ = this._zuiOverridePath
            ? this._http
                .get(`${this._zuiOverridePath}${lang}${this._suffix}`)
                .pipe(catchError(() => of({})))
            : of({});
        return forkJoin([zuiDefaults$, zuiFileOverrides$, userTranslations$]).pipe(map(([defaults, fileOverrides, user]) => ({
            ...defaults,
            ...fileOverrides,
            ...user,
        })));
    }
}
function zCreateTranslateLoader(http, path = './assets/i18n/', extension = '.json', includeZUI = true, zuiOverridePath, zuiLoader = zLoadDefaultZUITranslations) {
    return new ZTranslateHttpLoader(http, path, extension, includeZUI, zuiOverridePath, zuiLoader);
}
function initializeTranslate(defaultLang) {
    const translate = inject(TranslateService);
    const savedLang = ZCacheService.get(Z_LANG_CACHE_KEY) ?? defaultLang;
    ZCacheService.set(Z_LANG_CACHE_KEY, savedLang);
    translate.setFallbackLang(defaultLang);
    return firstValueFrom(translate.use(savedLang));
}
function provideZTranslate(config = {}) {
    const { defaultLang = 'vi', translationPath = './assets/i18n/', fileExtension = '.json', includeZUITranslations = true, zuiOverridePath, zuiTranslationsLoader = zLoadDefaultZUITranslations, } = config;
    return makeEnvironmentProviders([
        provideTranslateService({
            fallbackLang: defaultLang,
            loader: {
                provide: TranslateLoader,
                useFactory: (http) => zCreateTranslateLoader(http, translationPath, fileExtension, includeZUITranslations, zuiOverridePath, zuiTranslationsLoader),
                deps: [HttpClient],
            },
        }),
        provideAppInitializer(() => initializeTranslate(defaultLang)),
    ]);
}

/**
 * Z-NgxMask Provider Types
 */

/**
 * Generated bundle index. Do not edit.
 */

export { Z_CACHE_CONFIG, Z_INDEXDB_SERVICE, provideZCache, provideZIndexDb, provideZNgxMask, provideZScrollbar, provideZTheme, provideZTranslate, zCreateTranslateLoader };
//# sourceMappingURL=shival99-z-ui-providers.mjs.map
