import { AuthState } from './../../auth/store/auth.reducers';
import { AppState } from 'src/app/store/app.reducers';
import { CanActivate, RouterStateSnapshot, ActivatedRouteSnapshot, Router } from "@angular/router";
import { Observable, of } from "rxjs";
import { Store } from '@ngrx/store';
import { switchMap, map } from 'rxjs/operators';
import { HttpClient } from '@angular/common/http';
import { User } from '../model/user.model';

export abstract class AbstractRoleGuard implements CanActivate{
    
    constructor(private store: Store<AppState>, private http: HttpClient, private router: Router) {}

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | Observable<boolean> | Promise<boolean> {
        return this.store.select('authState').pipe(
            switchMap(
                (state: AuthState) => {
                    if (state.token === null){
                        this.router.navigate(['/']);
                        return of(false);
                    }
                    else{
                        if (state.user !== null){
                            if (this.hasRights(state.user))
                                return of(true);
                            else {
                                this.router.navigate(['/']);
                                return of(false);
                            }
                        }
                        else{
                            return this.http.get<User>('/tadis/users/profile').pipe(
                                map(
                                    (user: User) => {
                                        if (this.hasRights(user))
                                            return true;
                                        else {
                                            this.router.navigate(['/']);
                                            return false;
                                        }
                                    }
                                )
                            );
                        }
                    }
               } 
            )
        );
    }


    abstract hasRights(roleNameOrUser: String | User):boolean;

}