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

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

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

import { NGXLogger } from 'ngx-logger';
import * as RoomStore from '@app/store/messenger/room';
import * as SyncStore from '@app/store/messenger/sync';
import * as AuthStore from '@app/store/account/authentication';
import {
  bulkInfo,
  bulkInfoSuccess,
  bulkInfoFailure,
  status,
  statusFailure,
  statusSuccess,
  messageUpdate,
  messageUpdateFailure
} from './actions';
import {
  tap,
  switchMap,
  map,
  catchError,
  exhaustMap,
  delay
} from 'rxjs/operators';
import {
  StatusProtocolService,
  SSVC_TYPE_STATUS_BULK_INFO_DATA,
  SSVC_TYPE_STATUS_BULK_INFO_RES,
  BulkInfoData,
  StatusBulkInfo,
  StatusResponse,
  MessageUpdateResponse
} from '@ucap-webmessenger/protocol-status';
import { of } from 'rxjs';

@Injectable()
export class Effects {
  buddy2SuccessPostBulk$ = createEffect(() =>
    this.actions$.pipe(
      ofType(SyncStore.buddy2Success),
      map(params => {
        const userSeqList: number[] = [];
        for (const buddy of params.buddyList) {
          userSeqList.push(buddy.seq);
        }

        return bulkInfo({ divCd: 'bulk', userSeqs: userSeqList });
      })
    )
  );

  bulkInfo$ = createEffect(
    () => {
      let statusBulkInfoList: StatusBulkInfo[];

      return this.actions$.pipe(
        ofType(bulkInfo),
        tap(() => {
          statusBulkInfoList = [];
        }),
        switchMap(req => {
          return this.statusProtocolService.bulkInfo(req).pipe(
            map(res => {
              switch (res.SSVC_TYPE) {
                case SSVC_TYPE_STATUS_BULK_INFO_DATA:
                  statusBulkInfoList.push(
                    ...(res as BulkInfoData).statusBulkInfos
                  );
                  break;
                case SSVC_TYPE_STATUS_BULK_INFO_RES:
                  this.store.dispatch(
                    bulkInfoSuccess({
                      statusBulkInfoList
                    })
                  );
                  break;
              }
            }),
            catchError(error => of(bulkInfoFailure({ error })))
          );
        })
      );
    },
    { dispatch: false }
  );

  // statusNotification$ = createEffect(
  //   () => {
  //     return this.actions$.pipe(
  //       ofType(statusNotification),
  //       map(action => action.noti),
  //       tap(noti => {})
  //     );
  //   },
  //   { dispatch: false }
  // );

  status$ = createEffect(() =>
    this.actions$.pipe(
      ofType(status),
      map(action => action.req),
      exhaustMap(req => {
        return this.statusProtocolService.status(req).pipe(
          map((res: StatusResponse) => {
            return statusSuccess({ res });
          }),
          catchError(error => of(statusFailure({ error })))
        );
      })
    )
  );

  messageUpdate$ = createEffect(() =>
    this.actions$.pipe(
      ofType(messageUpdate),
      exhaustMap(action => {
        return this.statusProtocolService.messageUpdate(action).pipe(
          map((res: MessageUpdateResponse) => {
            return AuthStore.updateStatusMessageSuccess({ res });
          }),
          catchError(error => of(messageUpdateFailure({ error })))
        );
      })
    )
  );

  myStatusCheck$ = createEffect(
    () =>
      this.actions$.pipe(
        ofType(AuthStore.loginSuccess),
        map(action => action.loginRes),
        delay(5000),
        tap(loginRes => {
          this.store.dispatch(
            bulkInfo({ divCd: 'mybulk', userSeqs: [loginRes.userSeq] })
          );
          // return bulkInfo({ divCd: 'bulk', userSeqs: [loginRes.userSeq] });
        })
      ),
    { dispatch: false }
  );

  mroomUserStatusCheck$ = createEffect(
    () =>
      this.actions$.pipe(
        ofType(RoomStore.infoSuccess),
        map(action => action.userInfoList),
        tap(userInfoList => {
          if (!!userInfoList && userInfoList.length > 0) {
            this.store.dispatch(
              bulkInfo({
                divCd: 'roomuserBulk',
                userSeqs: userInfoList.map(userinfo => userinfo.seq)
              })
            );
          }
        })
      ),
    { dispatch: false }
  );

  constructor(
    private actions$: Actions,
    private store: Store<any>,
    private statusProtocolService: StatusProtocolService,
    private logger: NGXLogger
  ) {}
}