import { HttpErrorResponse } from '@angular/common/http';
import * as i0 from '@angular/core';
import { InjectionToken, inject, Injectable } from '@angular/core';
import * as i1 from '@angular/fire/auth';
import { Auth, idToken, authState, sendPasswordResetEmail, confirmPasswordReset, signInWithEmailAndPassword, signOut, GoogleAuthProvider, GithubAuthProvider, FacebookAuthProvider, TwitterAuthProvider, signInWithPopup, signInWithRedirect } from '@angular/fire/auth';
import { isDefined } from '@rxap/rxjs';
import { coerceArray } from '@rxap/utilities';
import { tap, switchMap, catchError, take, map } from 'rxjs/operators';
import { BehaviorSubject, EMPTY, firstValueFrom } from 'rxjs';
import { traceUntilFirst } from '@angular/fire/performance';

const IDENTITY_PLATFORM_HTTP_INTERCEPTOR_URL_PATTERN = new InjectionToken('identity-platform-http-interceptor-url-pattern');
const IdentityPlatformHttpInterceptor = (req, next) => {
    const urlPattern = coerceArray(inject(IDENTITY_PLATFORM_HTTP_INTERCEPTOR_URL_PATTERN, { optional: true }) ?? []);
    const auth = inject(Auth);
    const isMatch = (req) => {
        return urlPattern.some(pattern => req.url.match(pattern));
    };
    if (isMatch(req)) {
        return idToken(auth).pipe(tap(idTokenValue => {
            if (!idTokenValue) {
                throw new Error(`The isToken is not defined. Ensure that the user is logged in, before sending a request to '${req.url}'`);
            }
        }), isDefined(), switchMap(idTokenValue => next(req.clone({
            setHeaders: {
                idToken: idTokenValue,
            },
        })).pipe(catchError(error => {
            if (error instanceof HttpErrorResponse) {
                if (error.status === 401) {
                    auth.signOut().then(() => location.reload());
                }
            }
            throw error;
        }))));
    }
    return next(req);
};

class IdentityPlatformService {
    constructor(auth) {
        this.auth = auth;
        this.isAuthenticated$ = new BehaviorSubject(null);
        this.user = EMPTY;
        this.user = authState(this.auth);
        this.isAuthenticated().then(isAuthenticated => this.isAuthenticated$.next(isAuthenticated));
    }
    async requestPasswordReset(email) {
        await sendPasswordResetEmail(this.auth, email);
        return true;
    }
    async sendPasswordReset(password, token) {
        await confirmPasswordReset(this.auth, token, password);
        return true;
    }
    async signInWithEmailAndPassword(email, password, remember) {
        await signInWithEmailAndPassword(this.auth, email, password);
        this.isAuthenticated$.next(true);
        return true;
    }
    async signOut() {
        await signOut(this.auth);
        this.isAuthenticated$.next(false);
        return true;
    }
    google(popup = true) {
        return this.withProvider(new GoogleAuthProvider(), popup);
    }
    github(popup = true) {
        return this.withProvider(new GithubAuthProvider(), popup);
    }
    facebook(popup = true) {
        return this.withProvider(new FacebookAuthProvider(), popup);
    }
    twitter(popup = true) {
        return this.withProvider(new TwitterAuthProvider(), popup);
    }
    isAuthenticated() {
        return firstValueFrom(authState(this.auth).pipe(traceUntilFirst('auth'), take(1), map(Boolean)));
    }
    async withProvider(provider, popup = true) {
        const signIn = popup ? signInWithPopup(this.auth, provider) : signInWithRedirect(this.auth, provider);
        await signIn;
        this.isAuthenticated$.next(true);
        return true;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: IdentityPlatformService, deps: [{ token: i1.Auth }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: IdentityPlatformService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: IdentityPlatformService, decorators: [{
            type: Injectable
        }], ctorParameters: () => [{ type: i1.Auth }] });

// region 
// endregion

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

export { IDENTITY_PLATFORM_HTTP_INTERCEPTOR_URL_PATTERN, IdentityPlatformHttpInterceptor, IdentityPlatformService };
//# sourceMappingURL=rxap-firebase-auth.mjs.map
