import { ScanAdapterService } from '@adapter/scan';
import { inject, Injectable } from '@angular/core';
import { toSignal } from '@angular/core/rxjs-interop';
import { EnvironmentService } from '@core/environment';
import { UiConfirmModalComponent, UiModalResult, UiModalService } from '@ui/modal';
import { injectNetworkStatus$ } from '../../app/services';
import { AuthService } from './auth.service';
import { AuthService as IsaAuthService } from '@generated/swagger/isa-api';
import { firstValueFrom, lastValueFrom } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class LoginStrategy {
  private readonly environmentService = inject(EnvironmentService);
  private readonly networkStatus = toSignal(injectNetworkStatus$());
  private readonly modal = inject(UiModalService);
  private readonly scanAdapterService = inject(ScanAdapterService);
  private readonly isaAuthService = inject(IsaAuthService);
  private readonly authService = inject(AuthService);

  async login(title = 'Anmeldung') {
    console.log('LoginStrategy.login');

    let loginModalResult: UiModalResult<boolean>;

    if (this.authService.isIdTokenValid()) {
      console.log('LoginStrategy.login: idToken is valid');
      await this.authService.login();
      return;
    }

    try {
      if (this.environmentService.isMobileDevice()) {
        console.log('LoginStrategy.login: isMobileDevice');
        do {
          const loginModal = this.modal.open({
            content: UiConfirmModalComponent,
            title,
            config: {
              canClose: false,
              backdropClose: false,
            },
            data: {
              message: 'Bitte wählen Sie die Anmeldeoption aus.',
              rejectLabel: 'Anmeldung mit Logindaten',
              confirmLabel: 'Anmeldung mit Keycard',
            },
          });

          loginModalResult = await loginModal.afterClosed$.toPromise();
        } while (this.networkStatus() === 'offline');
      }
    } catch (error) {}

    try {
      if (loginModalResult.data) {
        const result = await lastValueFrom(this.scanAdapterService.scan());

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

          if (res.token) {
            console.log('LoginStrategy.login: setKeyCardToken', res.token);
            this.authService.setKeyCardToken(res.token);
          }
        }
      }
    } catch (error) {}

    console.log('LoginStrategy.login: login');
    await this.authService.login();
  }
}
