import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, CanActivateChild, CanLoad, Route, Router } from '@angular/router';
import { Observable, of } from 'rxjs';
import { BixiACService } from './ac.service';

@Injectable({ providedIn: 'root' })
export class BixiACGuard implements CanActivate, CanActivateChild, CanLoad {
  constructor(private acService: BixiACService, private router: Router) { }

  canActivate(route: ActivatedRouteSnapshot): Observable<boolean> {
    return of(this.hasPermissions(route));
  }

  canActivateChild(childRoute: ActivatedRouteSnapshot): Observable<boolean> {
    return this.canActivate(childRoute);
  }

  canLoad(route: Route): Observable<boolean> {
    return of(this.hasPermissions(route));
  }

  private hasPermissions(route: Route | ActivatedRouteSnapshot) {
    if (!(route && route.data && route.data.ac)) {
      return true;
    }
    const acData = route.data.ac || {};
    const { isRole = false, ac, acAny, ace, aceAny, redirectTo } = acData;
    if ([ac, acAny, ace, aceAny].filter(s => !!s).length > 1) {
      console.error(`[@bixi/ac] 同一个路由只能使用 ['ac', 'acAny', 'ace', 'aceAny'] 中一条规则`);
      return false;
    }
    let hasPermission = false;
    if (ac) {
      hasPermission = this.acService.ac(ac, { isRole });
    }
    if (acAny) {
      hasPermission = this.acService.acAny(acAny, { isRole });
    }
    if (ace) {
      hasPermission = this.acService.ace(ace, { isRole });
    }
    if (aceAny) {
      hasPermission = this.acService.aceAny(aceAny, { isRole });
    }
    if (!hasPermission && redirectTo) {
      console.log(`[@bixi/ac] 没有路由访问权限，重定向至 -> ${redirectTo}`, route);
      this.router.navigateByUrl(redirectTo);
      return hasPermission;
    }
    console.log(`[@bixi/ac] 没有路由访问权限`, route);
    return hasPermission;
  }
}
