/**
 * @license
 * Copyright Akveo. All Rights Reserved.
 * Licensed under the MIT License. See License.txt in the project root for license information.
 */
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { NbAuthSocialLink, NbAuthService, NB_AUTH_OPTIONS, NbAuthResult, getDeepFromObject } from '@nebular/auth';
import { Subject } from 'rxjs';
import { first, takeUntil } from 'rxjs/operators';
import { LoginTokenViewModel, RegisterViewModel } from '../entity/Auth';
import { AuthService } from '../services/auth.service';
import { PastoralDomainService } from '../services/crudServices/pastoral-domain.service';
import { SessionService } from '../services/session.service';

@Component({
  selector: 'ngx-login',
  templateUrl: './login.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class LoginComponent {

  private destroy$ = new Subject<void>();
  redirectDelay: number = 0;
  showMessages: any = {};
  strategy: string = '';

  errors: string[] = [];
  messages: string[] = [];
  user: RegisterViewModel = {} as RegisterViewModel;
  submitted: boolean = false;
  socialLinks: NbAuthSocialLink[] = [];
  rememberMe = false;
  displayRegister: boolean = false;
  confirmPassword: string = '';
  isCallback: boolean = false;
  constructor(
    protected service: NbAuthService,
    @Inject(NB_AUTH_OPTIONS) protected options = {},
    protected cd: ChangeDetectorRef,
    protected router: Router,
    private route: ActivatedRoute,
    private sessionService: SessionService,
    private authService: AuthService,
    private pastoralDomainService: PastoralDomainService
  ) {

    this.redirectDelay = this.getConfigValue('forms.login.redirectDelay');
    this.showMessages = this.getConfigValue('forms.login.showMessages');
    this.strategy = this.getConfigValue('forms.login.strategy');
    this.socialLinks = this.getConfigValue('forms.login.socialLinks');
    this.rememberMe = this.getConfigValue('forms.login.rememberMe');
  }

  ngOnInit(): void {
    this.route.url.pipe(first()).subscribe(urlSegments => {

      if (urlSegments[urlSegments.length - 1].path == 'googleLoginCallback') {
        console.log('googleLoginCallback');
        this.isCallback = true;
        this.googleOAuthAccess(true);
      } else if (urlSegments[urlSegments.length - 1].path == 'lineLogin') {
        console.log('lineLogin');
        this.isCallback = true;
        this.lineOAuthAccess();
      } else {
        this.route.queryParams.pipe(first()).subscribe(paramMap => {
          if (paramMap['return']) {
            this.sessionService.redirectAfterLogin = paramMap['return'];
          } else {
            //this.sessionService.redirectAfterLogin = '/pages/dashboard';
          }
        });
      }
    });
  }
  ngOnDestroy(): void {
    this.destroy$.next();
    this.destroy$.complete();
  }

  postData(): void {

    if (this.displayRegister && this.user.password !== this.confirmPassword) {
      return;
    }

    this.errors = [];
    this.messages = [];
    this.submitted = true;
    let authFunc = this.displayRegister ? this.authService.register(this.user) : this.authService.login(this.user);


    authFunc.subscribe((result: LoginTokenViewModel) => {
      this.submitted = false;


      if (result && result.token) {

        this.pastoralDomainService.initialize().pipe(first()).subscribe(result => {
          if (this.sessionService.redirectAfterLogin) {
            setTimeout(() => {
              return this.router.navigateByUrl(this.sessionService.redirectAfterLogin);
            }, this.redirectDelay);
          }
        });
      } else {
        this.errors = ['Invalid Credential.'];
      }

      this.cd.detectChanges();
    });
  }


  googleLogin() {
    this.googleOAuthAccess(false);
  }
  getConfigValue(key: string): any {
    return getDeepFromObject(this.options, key, null);
  }

  private googleOAuthAccess(isCallback: boolean) {

    this.service.authenticate('google')
      .pipe(first())
      .subscribe((authResult: NbAuthResult) => {
        if (isCallback) {
          this.authService.loginWithGoogleAccessToken(authResult.getToken().getValue())
            .pipe(first()).subscribe(result => {
              if (result) {
                this.pastoralDomainService.initialize().pipe(first()).subscribe(result => {
                  this.redirect();
                });
              } else {
                this.isCallback = false;
              }
            });
        }
      });
  }

  private lineOAuthAccess() {

    console.log('lineOAuthAccess()');
    this.route.queryParams.pipe(first()).subscribe(paramMap => {
      if (paramMap['code']) {

        let accessToken = paramMap['code'];
        let lineId = paramMap['liffClientId'];
        console.log('accessToken', accessToken);
        console.log('liffClientId', lineId);
        this.authService.loginWithLineAccessToken(accessToken);
      }
    });
  }
  private redirect() {

    if (this.sessionService.redirectAfterLogin) {
      setTimeout(() => {
        return this.router.navigateByUrl(this.sessionService.redirectAfterLogin);
      }, this.redirectDelay);
    }
  }
}
