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

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

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

import {
  dept,
  deptSuccess,
  deptFailure,
  myDeptUserSuccess,
  myDeptUser,
  myDeptUserFailure
} from './actions';

import {
  QueryProtocolService,
  DeptInfo,
  SSVC_TYPE_QUERY_DEPT_DATA,
  SSVC_TYPE_QUERY_DEPT_RES,
  DeptData,
  UserInfoSS,
  SSVC_TYPE_QUERY_DEPT_USER_DATA,
  DeptUserData,
  SSVC_TYPE_QUERY_DEPT_USER_RES,
  DeptUserResponse
} from '@ucap-webmessenger/protocol-query';

import { Store } from '@ngrx/store';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import { KEY_LOGIN_RES_INFO } from '@app/types';
import { SessionStorageService } from '@ucap-webmessenger/web-storage';

@Injectable()
export class Effects {
  dept$ = createEffect(
    () => {
      let departmentInfoList: DeptInfo[];

      return this.actions$.pipe(
        ofType(dept),
        tap(() => {
          departmentInfoList = [];
        }),
        switchMap(req => {
          return this.queryProtocolService.dept(req).pipe(
            map(res => {
              switch (res.SSVC_TYPE) {
                case SSVC_TYPE_QUERY_DEPT_DATA:
                  departmentInfoList.push(...(res as DeptData).departmentInfos);
                  break;
                case SSVC_TYPE_QUERY_DEPT_RES:
                  departmentInfoList.sort((a, b) =>
                    a.order < b.order ? -1 : a.order > b.order ? 1 : 0
                  );
                  this.store.dispatch(
                    deptSuccess({
                      departmentInfoList
                    })
                  );
                  break;
              }
            }),
            catchError(error => of(deptFailure({ error })))
          );
        })
      );
    },
    { dispatch: false }
  );

  myDeptUser$ = createEffect(
    () => {
      let userInfos: UserInfoSS[];

      return this.actions$.pipe(
        ofType(myDeptUser),
        tap(() => {
          userInfos = [];
        }),
        switchMap(req => {
          return this.queryProtocolService.deptUser(req).pipe(
            map(res => {
              switch (res.SSVC_TYPE) {
                case SSVC_TYPE_QUERY_DEPT_USER_DATA:
                  userInfos.push(...(res as DeptUserData).userInfos);
                  break;
                case SSVC_TYPE_QUERY_DEPT_USER_RES:
                  userInfos.sort((a, b) =>
                    a.order < b.order
                      ? -1
                      : a.order > b.order
                      ? 1
                      : a.name < b.name
                      ? -1
                      : a.name > b.name
                      ? 1
                      : 0
                  );

                  this.store.dispatch(
                    myDeptUserSuccess({
                      userInfos
                    })
                  );
                  break;
              }
            }),
            catchError(error => of(myDeptUserFailure({ error })))
          );
        })
      );
    },
    { dispatch: false }
  );

  constructor(
    private actions$: Actions,
    private store: Store<any>,
    private queryProtocolService: QueryProtocolService,
    private sessionStorageService: SessionStorageService
  ) {}
}
