import { Component, ElementRef, HostListener, OnInit, ViewChild } from '@angular/core';
import { UntypedFormBuilder, Validators } from '@angular/forms';
import { AuthService } from '../auth.service';
import { ActivatedRoute, Router } from '@angular/router';
import { ConfigService } from '../../config/config.service';
import { IAuthResultModel } from '../models/auth-result.model';
import { LogoLinkOptions } from '../../ui/logo/logo.component';
import { SFALoginDataService } from '@fleio-api/second-factor-authentication/sfa-login-data.service';
import { CartUtilsService } from '@fleio-api/billing/cart/cart-utils.service';
import { ThemingService } from '@shared/ui/theming/theming.service';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {
  @ViewChild('password') password: ElementRef; // used to make autofill with lastpass work on iphone's Google browser
  loginForm = this.formBuilder.group({
    email: ['', Validators.required],
    password: ['', Validators.required],
    rememberMe: [false]
  });
  logoLinkOptions = new LogoLinkOptions(false);
  navigationUrl: string;
  cardTopMargin: string;

  demoCredentials = {
    enduser: {
      email: 'demo@demo.fleio.com',
      password: 'demo'
    },
    staff: {
      email: 'demoadmin@demo.fleio.com',
      password: 'demoadmin'
    },
  };
  loading: boolean;

  @ViewChild('formErrors') formErrors;
  nextUrl: string;

  constructor(
    private formBuilder: UntypedFormBuilder, private router: Router,
    private activatedRoute: ActivatedRoute,
    public auth: AuthService, public config: ConfigService,
    private sfaLoginDataService: SFALoginDataService,
    private cartUtilsService: CartUtilsService,
    private themingService: ThemingService,
  ) {
  }

  ngOnInit() {
    if (this.auth.feature('demo')) {
      if (this.auth.feature('ui.core.demo-login-staff')) {
        this.loginForm.controls.email.setValue(this.demoCredentials.staff.email);
        this.loginForm.controls.password.setValue(this.demoCredentials.staff.password);
      } else if (this.auth.feature('ui.core.demo-login-enduser')) {
        this.loginForm.controls.email.setValue(this.demoCredentials.enduser.email);
        this.loginForm.controls.password.setValue(this.demoCredentials.enduser.password);
      }
    }
    this.loginForm.valueChanges.subscribe(() => {
      this.formErrors.hide();
    });
    const prevUrl = this.config.getPrevUrl();
    this.navigationUrl = prevUrl;
    if (this.config.getPanelUrl('logout') === prevUrl || this.config.getPanelHomeUrl() === prevUrl ||
      (prevUrl.indexOf('sfa/') > -1 && prevUrl.endsWith('confirm'))) {
      // If previous url is logout, rather redirect to dashboard after sfa confirm
      // If previous url is a confirm sfa page (user refreshed that page), redirect to dashboard otherwise user gets
      // stuck on the confirm page even if successfully submitted code.
      // setting navigation url to null if we want to redirect to, or we are on dashboard since we do not have
      // active client id here - getPanelHomeUrl will be called if this url is null to retrieve dashboard url when
      // active client id is available
      this.navigationUrl = null;
    }
    if (this.cartUtilsService.redirectToCart) {
      this.navigationUrl = this.config.getPanelUrl(`billing/cart`);
    }
    this.activatedRoute.params.subscribe(value => {
      if (value && value.invitationId && value.invitationToken) {
        this.navigationUrl = this.config.getPanelUrl(
          `invitations/${value.invitationId}/${value.invitationToken}`
        );
      }
    });
    this.activatedRoute.queryParams.subscribe(data => {
      if (data.nextUrl) {
        this.navigationUrl = data.nextUrl;
      }
    });
    this.setCardTopMargin(window.innerHeight);
    const nextUrl = this.config.getPanelUrl('saml2sso');
    this.nextUrl = window.location.href.replace(this.config.getCurrentUrl(), nextUrl);
  }

  @HostListener('window:resize', ['$event'])
  onResize() {
    this.setCardTopMargin(window.innerHeight);
  }

  private setCardTopMargin(innerHeight) {
    this.cardTopMargin = this.themingService.setOrphanCardMarginTop(innerHeight, 360);
  }

  login() {
    const email = this.loginForm.controls.email.value;
    // workaround to make autofill for password from lastpass work on iphone's Google browser
    this.loginForm.controls.password.setValue(this.password.nativeElement.value);
    const password = this.loginForm.controls.password.value;
    const rememberMe = this.loginForm.controls.rememberMe.value;
    this.loading = true;
    this.auth.login(
      email,
      password,
      rememberMe,
    ).subscribe({
      next: (authResult: IAuthResultModel) => {
        if (authResult.success) {
          if (authResult.sfaRequired) {
            let i = 0;
            for (const SFAMethod of authResult.sfaMethods) {
              i += 1;
              if (SFAMethod.default || i === authResult.sfaMethods.length) {
                const methodPath = SFAMethod.name.replace('_', '-');
                this.sfaLoginDataService.setLoginData(
                  email,
                  password,
                  rememberMe,
                  this.navigationUrl ? this.navigationUrl : this.config.getPanelHomeUrl(),
                  authResult.sfaMethods
                );
                return this.router.navigateByUrl(
                  this.config.getPanelUrl(`sfa/${methodPath}/confirm`)
                ).then(() => {
                });
              }
            }
          }
          this.router.navigateByUrl(
            this.navigationUrl ? this.navigationUrl : this.config.getPanelHomeUrl(),
          ).then(() => {
          });
        } else {
          this.loading = false;
          this.formErrors.showError(authResult.errorMessage);
        }
      },
      error: () => {
        this.loading = false;
      }
    });
  }
}
