import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot } from '@angular/router';
import { AuthService } from '@core/auth';
import { ScanAdapterService } from '@adapter/scan';
import { AuthService as IsaAuthService } from '@swagger/isa';
import { UiErrorModalComponent, UiModalService } from '@ui/modal';

@Injectable({ providedIn: 'root' })
export class IsAuthenticatedGuard implements CanActivate {
  constructor(
    private _authService: AuthService,
    private _scanService: ScanAdapterService,
    private _isaAuthService: IsaAuthService,
    private _modal: UiModalService
  ) {}

  async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    const authenticated = await this._authService.isAuthenticated();

    if (!authenticated) {
      const token = await this.scanAndGetToken();

      if (token) {
        this._authService.setKeyCardToken(token);
      }

      this._authService.login();
    }

    return authenticated;
  }

  async scanAndGetToken(): Promise<string> {
    const result = await this._scanService.scan()?.toPromise();

    if (typeof result === 'string') {
      try {
        const res = await this._isaAuthService
          .AuthLogin({
            code: result,
            application: 'isa',
            hostname: location.host,
          })
          .toPromise();

        return res.token;
      } catch (error) {
        const errorModalRef = this._modal.open({
          content: UiErrorModalComponent,
          title: 'Fehler bei der Anmeldung',
          data: {
            message: 'Versuchen Sie es erneut\noder melden Sie sich mit\nIhren Benutzerdaten an.',
          },
        });

        await errorModalRef.afterClosed$.toPromise();

        return this.scanAndGetToken();
      }
    }

    return undefined;
  }
}
