import { HttpClient } from '@angular/common/http';
import * as i0 from '@angular/core';
import { inject, Injectable } from '@angular/core';
import { I18nService } from '@sdcorejs/angular/i18n';
import { throwError } from 'rxjs';
import { catchError, switchMap } from 'rxjs/operators';
import * as i1 from '@angular/material/snack-bar';
import * as i1$1 from '@sdcorejs/angular/modules';

class SdNoInternetInterceptor {
    snackBar;
    injector;
    #i18n = inject(I18nService);
    // Trạng thái offline để tránh spam request check hoặc hiển thị nhiều snackbar
    #isOffline = false;
    // Giữ tham chiếu để có thể đóng/thao tác snackbar
    #snackBarRef = null;
    // Giữ tham chiếu interval để clear khi có mạng lại
    #pollInterval = null;
    // Lazy load HttpClient
    #http = null;
    // Endpoint kiểm tra mạng (Nên dùng 1 file tĩnh nhẹ hoặc API ping public uy tín)
    #healthCheckUrl = 'https://jsonplaceholder.typicode.com/todos/1';
    // Thời gian lặp lại việc kiểm tra mạng (ms)
    #checkIntervalDuration = 3000;
    constructor(snackBar, injector) {
        this.snackBar = snackBar;
        this.injector = injector;
    }
    intercept(request, next) {
        return next.handle(request).pipe(catchError((error) => {
            // --- TRƯỜNG HỢP 1: Lỗi mất kết nối (Status 0) ---
            if (error.status === 0 && !this.#isOffline) {
                this.#isOffline = true;
                // Lazy load HttpClient để tránh lỗi Circular Dependency
                if (!this.#http) {
                    this.#http = this.injector.get(HttpClient);
                }
                // Gọi thử một API public để xác minh xem là Mất mạng thật hay do CORS/Server chặn
                return this.#http.get(this.#healthCheckUrl).pipe(
                // 1. Ưu tiên bắt lỗi kết nối trước (Đây là logic MẤT MẠNG THẬT)
                catchError(_checkError => {
                    // Hiển thị thông báo và bắt đầu polling chờ mạng
                    this.#showReloadSnackbar(this.#i18n.t('core.interceptor.no-internet.offline'), { isSticky: true });
                    this.#startPolling();
                    // Ném lại lỗi gốc để Component biết request thất bại
                    return throwError(() => error);
                }), 
                // 2. Nếu không vào catchError ở trên -> Check thành công -> CÓ MẠNG
                // Lỗi status 0 ban đầu là do CORS, SSL, hoặc Server chặn connection
                switchMap(() => {
                    this.#isOffline = false; // Reset cờ
                    this.snackBar.open(this.#i18n.t('core.interceptor.no-internet.cors-error'), this.#i18n.t('core.common.close'), {
                        duration: 5000,
                        horizontalPosition: 'center',
                        verticalPosition: 'top',
                    });
                    // Ném lại lỗi gốc
                    return throwError(() => error);
                }));
            }
            // --- TRƯỜNG HỢP 2: Server bảo trì (503) ---
            else if (error.status === 503) {
                this.snackBar.open(this.#i18n.t('core.interceptor.no-internet.maintenance'), this.#i18n.t('core.common.close'), {
                    horizontalPosition: 'center',
                    verticalPosition: 'top',
                    duration: 5000,
                });
            }
            // --- TRƯỜNG HỢP KHÁC: 401, 404, 500... ---
            // Ném lỗi ra để component xử lý bình thường
            return throwError(() => error);
        }));
    }
    /**
     * Hiển thị Snackbar thông báo trạng thái mạng
     */
    #showReloadSnackbar = (message, options) => {
        // Đóng snackbar cũ nếu đang hiện
        if (this.#snackBarRef) {
            this.#snackBarRef.dismiss();
        }
        this.#snackBarRef = this.snackBar.open(message, this.#i18n.t('core.common.reload'), {
            horizontalPosition: 'center',
            verticalPosition: 'top',
            // Nếu isSticky = true (mất mạng) -> Không tự tắt. Nếu có duration -> tự tắt.
            duration: options?.duration,
            panelClass: options?.isSticky ? ['offline-snackbar'] : undefined, // Class CSS tùy chọn
        });
        // Xử lý sự kiện bấm nút "Tải lại trang"
        this.#snackBarRef.onAction().subscribe(() => {
            window.location.reload();
        });
    };
    /**
     * Bắt đầu vòng lặp kiểm tra kết nối mạng
     */
    #startPolling = () => {
        this.#stopPolling(); // Clear cũ nếu có
        // @i18n-ignore — dev console log
        console.log('--- Bắt đầu chế độ theo dõi mạng ---');
        this.#pollInterval = setInterval(() => {
            if (!this.#http) {
                this.#http = this.injector.get(HttpClient);
            }
            // Check nhẹ
            this.#http.get(this.#healthCheckUrl).subscribe({
                next: () => {
                    // --> ĐÃ CÓ MẠNG LẠI
                    // @i18n-ignore — dev console log
                    console.log('--> Kết nối đã được khôi phục!');
                    this.#stopPolling();
                    this.#isOffline = false;
                    // Thông báo thành công (tự tắt sau 5s)
                    this.#showReloadSnackbar(this.#i18n.t('core.interceptor.no-internet.restored'), { duration: 5000, isSticky: false });
                },
                error: () => {
                    // --> VẪN MẤT MẠNG: Không làm gì cả, chờ lần check tiếp theo
                },
            });
        }, this.#checkIntervalDuration);
    };
    /**
     * Dừng vòng lặp kiểm tra
     */
    #stopPolling = () => {
        if (this.#pollInterval) {
            clearInterval(this.#pollInterval);
            this.#pollInterval = null;
        }
    };
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdNoInternetInterceptor, deps: [{ token: i1.MatSnackBar }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
    static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdNoInternetInterceptor });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdNoInternetInterceptor, decorators: [{
            type: Injectable
        }], ctorParameters: () => [{ type: i1.MatSnackBar }, { type: i0.Injector }] });

class SdUnauthorizedInterceptor {
    authService;
    #unauthorizedHandled = false;
    constructor(authService) {
        this.authService = authService;
    }
    intercept(request, next) {
        return next.handle(request).pipe(catchError((error) => {
            if (error.status === 401 && !this.#unauthorizedHandled) {
                this.#unauthorizedHandled = true;
                this.authService.signout();
            }
            return throwError(() => error);
        }));
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdUnauthorizedInterceptor, deps: [{ token: i1$1.SdAuthService }], target: i0.ɵɵFactoryTarget.Injectable });
    static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdUnauthorizedInterceptor });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdUnauthorizedInterceptor, decorators: [{
            type: Injectable
        }], ctorParameters: () => [{ type: i1$1.SdAuthService }] });

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

export { SdNoInternetInterceptor, SdUnauthorizedInterceptor };
//# sourceMappingURL=sdcorejs-angular-interceptors.mjs.map
