import { Injectable } from '@angular/core';
import { CanActivate, CanActivateChild, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { Observable, of } from 'rxjs';
import { map, take, tap } from 'rxjs/operators';
import { AuthService } from '../services/auth.service';

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

  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean> {
    return this.checkAuth(route, state.url);
  }

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

  private checkAuth(route: ActivatedRouteSnapshot, redirectUrl: string): Observable<boolean> {
    return this.authService.isAuthenticated$.pipe(
      take(1),
      map(isAuthenticated => {
        if (isAuthenticated) {
          // Check for required scopes if specified
          const requiredScopes = route.data?.['requiredScopes'] as string[];
          if (requiredScopes && requiredScopes.length > 0) {
            const hasScopes = route.data?.['requireAllScopes'] 
              ? this.authService.hasAllScopes(requiredScopes)
              : this.authService.hasAnyScope(requiredScopes);
            
            if (!hasScopes) {
              this.handleUnauthorized(route.data?.['unauthorizedRedirect']);
              return false;
            }
          }
          return true;
        } else {
          this.handleUnauthenticated(redirectUrl, route.data?.['loginRedirect']);
          return false;
        }
      })
    );
  }

  private handleUnauthenticated(redirectUrl: string, customLoginPath?: string): void {
    const loginPath = customLoginPath || '/login';
    this.router.navigate([loginPath], {
      queryParams: { returnUrl: redirectUrl }
    });
  }

  private handleUnauthorized(customUnauthorizedPath?: string): void {
    const unauthorizedPath = customUnauthorizedPath || '/unauthorized';
    this.router.navigate([unauthorizedPath]);
  }
}