import { Injectable } from '@angular/core';
import { Router } from '@angular/router';

import { Actions, ofType, createEffect } from '@ngrx/effects';

import { of } from 'rxjs';
import { catchError, exhaustMap, map } from 'rxjs/operators';

import {
  PiService,
  UserTermsActionResponse,
  ResponseStatus
} from '@ucap-webmessenger/pi';
import {
  DialogService,
  ConfirmDialogComponent,
  ConfirmDialogData,
  ConfirmDialogResult
} from '@ucap-webmessenger/ui';

import { AppAuthenticationService } from '@app/services/authentication.service';
import { loginSuccess, logout } from '../authentication';
import {
  agreeConfirmationYes,
  agreeConfirmationNo,
  agreeConfirmationNotNeeded,
  agreeSuccess,
  agreeFailure
} from './actions';
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import { LoginInfo, KEY_LOGIN_INFO } from '@app/types';

import { initSettings } from '@app/store/setting/init';

@Injectable()
export class Effects {
  agreeConfirmation$ = createEffect(() =>
    this.actions$.pipe(
      ofType(loginSuccess),
      exhaustMap(async params => {
        if (params.loginInfo.privateInformationAgree) {
          return null;
        }
        const loginInfo = this.sessionStorageService.get<LoginInfo>(
          KEY_LOGIN_INFO
        );

        const privacyTotalUrl = this.piService.privacyTotalUrl({
          companyCode: params.loginInfo.companyCode,
          userSeq: params.loginInfo.userSeq,
          token: params.loginInfo.tokenString,
          deviceType: loginInfo.deviceType,
          localeCode: loginInfo.localeCode,
          textOnly: 'true'
        });

        const result = await this.dialogService.open<
          ConfirmDialogComponent,
          ConfirmDialogData,
          ConfirmDialogResult
        >(ConfirmDialogComponent, {
          width: '100%',
          height: '500px',
          disableClose: true,
          data: {
            title: '개인정보 동의',
            html: `<iframe id="ifm_privacy" src="${privacyTotalUrl}" style="width: 100%;height: 300px;" />`
          }
        });

        return {
          loginInfo: params.loginInfo,
          choice: result.choice
        };
      }),
      map(params => {
        if (!params) {
          return agreeConfirmationNotNeeded();
        }

        return params.choice
          ? agreeConfirmationYes({ loginInfo: params.loginInfo })
          : agreeConfirmationNo();
      })
    )
  );

  agreeConfirmationYes$ = createEffect(() =>
    this.actions$.pipe(
      ofType(agreeConfirmationYes),
      map(action => {
        const loginInfo = this.sessionStorageService.get<LoginInfo>(
          KEY_LOGIN_INFO
        );

        return {
          loginInfo,
          loginResponse: action.loginInfo
        };
      }),
      exhaustMap(params =>
        this.piService
          .userTermsAction({
            userSeq: params.loginResponse.userSeq,
            token: params.loginResponse.tokenString,
            deviceType: params.loginInfo.deviceType
          })
          .pipe(
            map((res: UserTermsActionResponse) => {
              if ('00' !== res.responseCode) {
                return agreeFailure({ error: 'Failed' });
              } else {
                return agreeSuccess();
              }
            }),
            catchError(error => of(agreeFailure({ error })))
          )
      )
    )
  );

  agreeSuccess$ = createEffect(() =>
    this.actions$.pipe(
      ofType(agreeSuccess),
      map(() => initSettings())
    )
  );

  agreeFailure$ = createEffect(() =>
    this.actions$.pipe(
      ofType(agreeFailure),
      map(action => action),
      map(() => logout())
    )
  );

  constructor(
    private actions$: Actions,
    private router: Router,
    private piService: PiService,
    private sessionStorageService: SessionStorageService,
    private appAuthenticationService: AppAuthenticationService,
    private dialogService: DialogService
  ) {}
}
