import * as i0 from '@angular/core';
import { InjectionToken, Injectable, inject, provideAppInitializer, makeEnvironmentProviders, APP_INITIALIZER, NgModule } from '@angular/core';
import Keycloak from 'keycloak-js';
import { from, switchMap } from 'rxjs';

const SD_KEYCLOAK_CONFIGURATION = new InjectionToken('sd-keycloak.configuration');

class SdKeycloakService {
    keycloak;
    config;
    async init(config) {
        this.config = config;
        // 1. Khởi tạo instance
        this.keycloak = new Keycloak({
            url: config.url,
            realm: config.realm,
            clientId: config.clientId,
        });
        // 2. Lắng nghe sự kiện hết hạn token để tự động làm mới ngầm
        this.keycloak.onTokenExpired = () => {
            this.keycloak.updateToken(30).catch(() => {
                console.warn('Không thể làm mới token. Yêu cầu đăng nhập lại.');
                this.keycloak.login();
            });
        };
        // 3. Thực thi quá trình boot Keycloak
        return this.keycloak.init({
            onLoad: 'check-sso',
            silentCheckSsoRedirectUri: window.location.origin + '/silent-renew.html',
            checkLoginIframe: false, // Tắt check Iframe để chống lỗi vòng lặp
        });
    }
    // Tiện ích nhanh cho Dev sử dụng
    login() { return this.keycloak.login(); }
    logout() { return this.keycloak.logout({ redirectUri: window.location.origin }); }
    getToken() { return this.keycloak.token; }
    getIsAuthenticated() { return this.keycloak.authenticated; }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdKeycloakService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
    static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdKeycloakService, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdKeycloakService, decorators: [{
            type: Injectable,
            args: [{ providedIn: 'root' }]
        }] });

const SdKeycloakInterceptor = (req, next) => {
    const keycloakService = inject(SdKeycloakService);
    const { keycloak, config } = keycloakService;
    // Nếu chưa init xong hoặc chưa đăng nhập -> cho request đi qua bình thường
    if (!keycloak || !keycloak.authenticated || !config) {
        return next(req);
    }
    // Kiểm tra xem URL của request có nằm trong mảng secureRoutes không
    const isSecure = config.secureRoutes?.some(route => req.url.includes(route));
    if (!isSecure) {
        return next(req);
    }
    // Đảm bảo token luôn hợp lệ (cập nhật nếu token sẽ hết hạn trong 30s tới)
    return from(keycloak.updateToken(30)).pipe(switchMap(() => {
        const authReq = req.clone({
            headers: req.headers.set('Authorization', `Bearer ${keycloak.token}`)
        });
        return next(authReq);
    }));
};

// =======================================================================
// CÁCH 1: Dùng cho Angular 19 Standalone (Gọi trong app.config.ts)
// =======================================================================
function provideSdKeycloak(options) {
    // FIX 1: Khai báo mảng nhận cả Provider (cho Service/Token) lẫn EnvironmentProviders (cho AppInitializer)
    const providers = [SdKeycloakService];
    if (options.useFactory) {
        providers.push({ provide: SD_KEYCLOAK_CONFIGURATION, useFactory: options.useFactory, deps: options.deps || [] });
    }
    else if (options.useClass) {
        providers.push({ provide: SD_KEYCLOAK_CONFIGURATION, useClass: options.useClass });
    }
    // Standalone dùng được provideAppInitializer ngon lành
    providers.push(provideAppInitializer(() => {
        const configLoader = inject(SD_KEYCLOAK_CONFIGURATION);
        const keycloakService = inject(SdKeycloakService);
        return configLoader.loadTenantConfig().then((config) => keycloakService.init(config));
    }));
    return makeEnvironmentProviders(providers);
}
// =======================================================================
// CÁCH 2: Dùng cho kiến trúc NgModule cũ (Backward Compatibility)
// =======================================================================
class SdKeycloakModule {
    static forRoot(options) {
        return {
            ngModule: SdKeycloakModule,
            providers: [
                SdKeycloakService,
                ...(options.useFactory
                    ? [{ provide: SD_KEYCLOAK_CONFIGURATION, useFactory: options.useFactory, deps: options.deps || [] }]
                    : [{ provide: SD_KEYCLOAK_CONFIGURATION, useClass: options.useClass }]),
                // FIX 2: NgModule bắt buộc phải dùng APP_INITIALIZER (nhưng viết kiểu xịn của Angular 14+, dùng inject)
                {
                    provide: APP_INITIALIZER,
                    multi: true,
                    useFactory: () => {
                        const configLoader = inject(SD_KEYCLOAK_CONFIGURATION);
                        const keycloakService = inject(SdKeycloakService);
                        return () => configLoader.loadTenantConfig().then((config) => keycloakService.init(config));
                    }
                }
            ]
        };
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdKeycloakModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
    static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.17", ngImport: i0, type: SdKeycloakModule });
    static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdKeycloakModule });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdKeycloakModule, decorators: [{
            type: NgModule,
            args: [{}]
        }] });

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

export { SD_KEYCLOAK_CONFIGURATION, SdKeycloakInterceptor, SdKeycloakModule, SdKeycloakService, provideSdKeycloak };
//# sourceMappingURL=sd-angular-core-modules-keycloak.mjs.map
