import { Subject } from 'rxjs';
import { take, takeUntil } from 'rxjs/operators';

import { Component, OnInit, OnDestroy, Input, ViewChild } from '@angular/core';

import { MatCheckbox } from '@angular/material/checkbox';

import { Store, select } from '@ngrx/store';

import { Company } from '@ucap/api-external';
import { LoginTry } from '@ucap/pi';

import { LogService } from '@ucap/ng-logger';
import { I18nService } from '@ucap/ng-i18n';
import { SessionStorageService } from '@ucap/ng-web-storage';
import { PiService } from '@ucap/ng-pi';
import { ProtocolService } from '@ucap/ng-protocol';
import { CompanyActions, CompanySelector } from '@ucap/ng-store-organization';
import { LoginActions } from '@ucap/ng-store-authentication';

import { UserStore } from '@app/models/user-store';
import { LoginSession } from '@app/models/login-session';
import { AppKey } from '@app/types/app-key.type';
import { AppAuthenticationService } from '@app/services/app-authentication.service';

@Component({
  selector: 'app-sections-account-login',
  templateUrl: './login.section.component.html',
  styleUrls: ['./login.section.component.scss']
})
export class LoginSectionComponent implements OnInit, OnDestroy {
  @Input()
  companyGroupCode: string;

  @Input()
  fixedCompanyCode: string;

  @Input()
  userStore: UserStore;

  @Input()
  useRememberMe: boolean;

  @Input()
  useAutoLogin: boolean;

  @ViewChild('chkUseRememberMe', { static: false })
  chkUseRememberMe: MatCheckbox;

  @ViewChild('chkUseAutoLogin', { static: false })
  chkUseAutoLogin: MatCheckbox;

  loginSession: LoginSession;
  companyList: Company[];
  disableLoginForm = false;
  loginProcessing = false;
  loginTry: LoginTry;

  private ngOnDestroySubject = new Subject<boolean>();

  constructor(
    private piService: PiService,
    private protocolService: ProtocolService,
    private sessionStorageService: SessionStorageService,
    private i18nService: I18nService,
    private store: Store<any>,
    private appAuthenticationService: AppAuthenticationService,
    private logService: LogService
  ) {}

  ngOnInit(): void {
    this.ngOnDestroySubject = new Subject<boolean>();

    this.appAuthenticationService
      .getLoginSession$()
      .pipe(takeUntil(this.ngOnDestroySubject))
      .subscribe((loginSession) => (this.loginSession = loginSession));

    this.sessionStorageService
      .get$<LoginTry>(AppKey.LoginTry)
      .pipe(takeUntil(this.ngOnDestroySubject))
      .subscribe((loginTry) => (this.loginTry = loginTry));

    this.protocolService.disconnect();

    this.store.dispatch(
      CompanyActions.companies({
        req: { companyGroupCode: this.companyGroupCode }
      })
    );

    this.store
      .pipe(
        takeUntil(this.ngOnDestroySubject),
        select(CompanySelector.companyList)
      )
      .subscribe((companyList) => {
        this.companyList = companyList;
      });
  }

  ngOnDestroy(): void {
    if (!!this.ngOnDestroySubject) {
      this.ngOnDestroySubject.complete();
    }
  }

  onLogin(event: {
    companyCode: string;
    loginId: string;
    loginPw: string;
    notValid: () => void;
  }) {
    const useRememberMe: boolean = this.chkUseRememberMe.checked;
    const useAutoLogin: boolean = this.chkUseAutoLogin.checked;

    this.disableLoginForm = true;
    this.loginProcessing = true;

    this.piService
      .login2({
        companyCode: event.companyCode,
        loginId: event.loginId,
        loginPw: event.loginPw,
        deviceType: this.loginSession.deviceType
      })
      .pipe(take(1))
      .subscribe(
        (res) => {
          if ('success' !== res.status.toLowerCase()) {
            this.onWebLoginFailure(event, res.status);
            return;
          } else {
            this.store.dispatch(
              LoginActions.webLoginSuccess({
                companyCode: event.companyCode,
                loginId: event.loginId,
                loginPw: event.loginPw,
                autoLogin: useAutoLogin,
                rememberMe: useRememberMe,
                login2Response: res
              })
            );
            return;
          }
        },
        (error) => {
          this.onWebLoginFailure(event, error);
        },
        () => {
          this.disableLoginForm = false;
          this.loginProcessing = false;
        }
      );
  }

  onClickForgotPassword(lng: string) {
    this.i18nService.changeLanguage(lng);
  }

  private onWebLoginFailure(
    event: {
      companyCode: string;
      loginId: string;
      loginPw: string;
      notValid: () => void;
    },
    error: any
  ) {
    this.store.dispatch(LoginActions.webLoginFailure({ error }));

    event.notValid();
  }
}
