import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { AuthService } from '../services/auth.service';
import { RequestError } from '../services/requesterror';
import { UserService } from '../services/user.service';
import { I18nService } from '../services/i18n.service';


@Injectable({
    providedIn: 'root'
})
export class AuthUpdateGuard implements CanActivate {
    constructor(private authService: AuthService) { }

    canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        this.authService.getAuth().catch(function (error) { });
        return true;
    }
}

@Injectable({
    providedIn: 'root'
})
export class AuthGuard implements CanActivate {
    constructor(private authService: AuthService, private router: Router) { }

    canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        const that = this;
        return this.authService.getAuth().then(response => {
            return true;
        }).catch(function (error) {
            if (error instanceof RequestError && (error as RequestError).getResponse().status == 401) {
                return true;
            }

            return that.router.navigateByUrl(that.router.parseUrl('/unavailable?target=' + encodeURIComponent(state.url)), { skipLocationChange: true });
        });
    }
}

@Injectable({
    providedIn: 'root'
})
export class AuthenticatedGuard implements CanActivate {
    constructor(private authService: AuthService, private userService: UserService, private i18nService: I18nService, private router: Router) { }

    canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        const that = this;
        return this.authService.getAuth().then((data: any) => {
            this.userService.get().subscribe({
                next: (user: any) => {
                    let updateLocale = false;
                    let updateTheme = false;
                    let darktheme = 'false';

                    if (user.darkTheme) {
                        darktheme = 'true';
                    }

                    if (darktheme != localStorage.getItem("buntspecht.darkTheme")) {
                        localStorage.setItem("buntspecht.darkTheme", darktheme);
                        updateTheme = true;
                    }

                    if (this.i18nService.locales.indexOf(user.locale) != -1 && localStorage.getItem("buntspecht.locale") != user.locale) {
                        if (this.i18nService.locale != user.locale) {
                            localStorage.setItem("buntspecht.locale", user.locale);
                            updateLocale = true;
                        }
                    }
                    if (updateLocale || updateTheme) {
                        window.location.reload();
                    }
                }
            });

            return true;
        }).catch(function (error) {
            if (error instanceof RequestError && (error as RequestError).getResponse().status == 401) {
                return that.router.navigateByUrl(that.router.parseUrl('/login?target=' + encodeURIComponent(state.url)));
            }

            return that.router.navigateByUrl(that.router.parseUrl('/unavailable?target=' + encodeURIComponent(state.url)), { skipLocationChange: true });
        });
    }
}



@Injectable({
    providedIn: 'root'
})
export class AuthAdminGuard implements CanActivate {
    constructor(private authService: AuthService, private router: Router) { }

    canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        const that = this;
        return this.authService.getAuth().then(data => {
            if (data.authorities && data.authorities.find((role) => role.authority == 'ROLE_ADMIN') != undefined) {
                return true;
            }
            return that.router.navigateByUrl(that.router.parseUrl('/not-found'), { skipLocationChange: true });
        }).catch(function (error) {
            if (error instanceof RequestError && (error as RequestError).getResponse().status == 401) {
                return that.router.navigateByUrl(that.router.parseUrl('/login?target=' + encodeURIComponent(state.url)));
            }

            return that.router.navigateByUrl(that.router.parseUrl('/not-found'), { skipLocationChange: true });
        });
    }
}

@Injectable({
    providedIn: 'root'
})
export class AnonymousGuard implements CanActivate {
    constructor(private authService: AuthService, private router: Router) { }

    canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        const that = this;
        return this.authService.getAuth().then((data: any) => {
            this.router.navigateByUrl('/');
            return false;
        }).catch(function (error) {
            if (error instanceof RequestError && (error as RequestError).getResponse().status == 401) {
                return true;
            }
            return that.router.navigateByUrl(that.router.parseUrl('/unavailable?target=' + encodeURIComponent(state.url)), { replaceUrl: true });
        });
    }

}