import { Component, OnInit } from '@angular/core';
import { GoogleAuthenticatorApiService } from '@fleio-api/plugins/google-authenticator/google-authenticator-api.service';
import { ConfigService } from '@shared/config/config.service';
import { NotificationService } from '@shared/ui-api/notification.service';
import { EMPTY } from 'rxjs';
import { UntypedFormBuilder, Validators } from '@angular/forms';
import { DetailsFormBase } from '@objects-view/details-form-base';
import { Router } from '@angular/router';
import { HttpClient } from '@angular/common/http';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { CartUtilsService } from '@fleio-api/billing/cart/cart-utils.service';
import { AuthService } from '@shared/auth/auth.service';
import { CookiesHelper } from '@shared/ui-api/helpers/cookies-helper';

@Component({
  selector: 'app-google-authenticator-details-tab',
  templateUrl: './google-authenticator-details-tab.component.html',
  styleUrls: ['./google-authenticator-details-tab.component.scss']
})
export class GoogleAuthenticatorDetailsTabComponent extends DetailsFormBase<any> implements OnInit {
  gaForm = this.formBuilder.group({
    code: ['', [Validators.required, Validators.pattern('[0-9]*')]]
  });
  backendErrors = {};
  status: {
    enabled: boolean;
    default: boolean;
  };
  secretKey: string;
  imageLocation: string;
  imageData: SafeHtml;
  loading = false;

  constructor(
    private googleAuthenticatorApiService: GoogleAuthenticatorApiService,
    public config: ConfigService,
    private notificationService: NotificationService,
    private formBuilder: UntypedFormBuilder,
    private router: Router,
    private httpClient: HttpClient,
    private sanitizer: DomSanitizer,
    private cartUtilsService: CartUtilsService,
    private authService: AuthService,
  ) {
    super();
    this.imageLocation = this.config.getPanelApiUrl('plugins/google_authenticator/api/get_qr_code');
  }

  private processConfirmPassError() {
    this.notificationService.showMessage($localize`You need to confirm password`);
    this.router.navigateByUrl(this.config.getPanelUrl('sfa/confirm-password')).then(() => {});
  }

  getGAData() {
    this.loading = true;
    this.googleAuthenticatorApiService.getStatus().subscribe(response => {
      this.status = response;
      this.loading = false;
      this.getSecretKey();
      this.getQRImage();
    }, error => {
      if (error.status === 403) {
        this.processConfirmPassError();
        this.loading = false;
      } else {
        this.notificationService.showMessage($localize`Failed to get second factor auth method status`);
        this.loading = false;
      }
    });
  }

  getSecretKey() {
    this.loading = true;
    this.googleAuthenticatorApiService.getCode().subscribe(response => {
      this.secretKey = response.secret_key;
      this.loading = false;
    }, error => {
      if (error.status === 403) {
        this.processConfirmPassError();
        this.loading = false;
      } else {
        this.notificationService.showMessage($localize`Failed to get secret key`);
        this.loading = false;
      }
    });
  }

  getQRImage() {
    this.httpClient.get(this.imageLocation, {responseType: 'blob'}).subscribe(response => {
      this.imageData = this.sanitizer.bypassSecurityTrustUrl(URL.createObjectURL(response));
    });
  }

  refreshGoogleData() {
    this.getGAData();
  }

  ngOnInit(): void {
    this.refreshGoogleData();
  }

  enable() {
    this.validate();
    if (this.gaForm.invalid) {
      this.displayControlErrors();
      return EMPTY;
    }

    const value = this.gaForm.value;

    this.loading = true;
    this.googleAuthenticatorApiService.enable(value.code).subscribe(() => {
      this.refreshGoogleData();
      if (this.authService.feature('ui.enduser') && this.cartUtilsService.redirectToCart) {
        this.router.navigateByUrl(this.config.getPanelUrl(`billing/cart`)).then(()=>{});
      }
    }, error => {
      if (error.error) {
        this.setErrors(error.error);
      }
      this.refreshGoogleData();
    });
  }

  disable() {
    const dialogResult$ = this.notificationService.confirmDialog({
      title: $localize`Disable Google Authenticator?`,
      message: $localize`Are you sure?`,
    });
    dialogResult$.subscribe(dialogResult => {
      if (dialogResult?.button === 'yes') {
        this.googleAuthenticatorApiService.disable().subscribe(() => {
          this.refreshGoogleData();
        }, () => {
          this.notificationService.showMessage($localize`Failed to disable second factor auth method.`);
        });
      }
    });
  }

  regenerate() {
    const dialogResult$ = this.notificationService.confirmDialog({
      title: $localize`Regenerate code`,
      message: $localize`Are you sure?`,
      flags: [{
        id: 'regenerate',
        message: $localize`I am sure that I want to regenerate authenticator data and disable this method (if activated) until I re-activate it`,
        warningOnSelect: $localize`You will have to re-enable Google Authenticator (if activated) and this will make your old key obsolete`,
        selected: false,
      }],
      disableConfirmTillFlagsSelected: ['regenerate']
    });
    dialogResult$.subscribe(dialogResult => {
      // @ts-ignore
      if (dialogResult?.button === 'yes') {
        this.googleAuthenticatorApiService.regenerate().subscribe(() => {
          let rememberSFACookieSuffix: string;
          if (this.config.authService.feature('ui.staff')) {
            rememberSFACookieSuffix = 'staff';
          } else {
            rememberSFACookieSuffix = 'enduser';
          }
          CookiesHelper.clearCookie(`rSFA-${rememberSFACookieSuffix}`);
          window.location.reload();
        }, (error) => {
          if (error.status === 403) {
            this.processConfirmPassError();
          } else {
            this.notificationService.showMessage($localize`Failed to regenerate code for Google Authenticator.`);
          }
        });
      }
    });
  }

  makeDefault() {
    const dialogResult$ = this.notificationService.confirmDialog({
      title: $localize`Set Google Authenticator as default`,
      message: $localize`Are you sure?`,
    });
    dialogResult$.subscribe(dialogResult => {
      if (dialogResult?.button === 'yes') {
        this.googleAuthenticatorApiService.makeDefault().subscribe(() => {
          this.refreshGoogleData();
        }, () => {
          this.notificationService.showMessage(
            $localize`Failed to make Google Authenticator the default second factor auth method.`
          );
        });
      }
    });
  }

}
