import { Component, OnInit, Inject, OnDestroy } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA, PageEvent } from '@angular/material';
import { KEY_VER_INFO } from '@app/types';
import { SessionStorageService } from '@ucap-webmessenger/web-storage';

import { Store, select } from '@ngrx/store';
import * as AppStore from '@app/store';
import * as StatusStore from '@app/store/messenger/status';
import {
  UserInfoSS,
  QueryProtocolService,
  DeptSearchType,
  SSVC_TYPE_QUERY_DEPT_USER_DATA,
  DeptUserData,
  SSVC_TYPE_QUERY_DEPT_USER_RES,
  DeptUserResponse
} from '@ucap-webmessenger/protocol-query';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import { map, catchError, take, tap } from 'rxjs/operators';
import { Subscription, of, Observable } from 'rxjs';
import { EnvironmentsInfo, KEY_ENVIRONMENTS_INFO } from '@app/types';
import { NGXLogger } from 'ngx-logger';
import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native';
import { environment } from '../../../../../environments/environment';
import { StatusBulkInfo } from '@ucap-webmessenger/protocol-status';
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
import { DaesangProtocolService } from '@ucap-webmessenger/daesang';
import { DialogService } from '@ucap-webmessenger/ui';
import {
  ProfileDialogComponent,
  ProfileDialogData,
  ProfileDialogResult
} from '../profile/profile.dialog.component';

export interface IntegratedSearchDialogData {
  keyword: string;
}

export interface IntegratedSearchDialogResult {}

@Component({
  selector: 'app-integrated-search.dialog',
  templateUrl: './integrated-search.dialog.component.html',
  styleUrls: ['./integrated-search.dialog.component.scss']
})
export class IntegratedSearchDialogComponent implements OnInit, OnDestroy {
  loginRes: LoginResponse;
  loginResSubscription: Subscription;
  sessionVerinfo: VersionInfo2Response;
  environmentsInfo: EnvironmentsInfo;

  presence$: Observable<StatusBulkInfo[]>;
  searchSubscription: Subscription;
  searchUserInfos: UserInfoSS[] = [];
  searchingProcessing = false;

  currentSearchWord: string;
  totalCount = 0;
  pageCurrent = 1;
  pageListCount = 20;

  constructor(
    public dialogRef: MatDialogRef<
      IntegratedSearchDialogData,
      IntegratedSearchDialogResult
    >,
    @Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService,
    @Inject(MAT_DIALOG_DATA) public data: IntegratedSearchDialogData,
    private queryProtocolService: QueryProtocolService,
    private sessionStorageService: SessionStorageService,
    private daesangProtocolService: DaesangProtocolService,
    private dialogService: DialogService,
    private store: Store<any>,
    private logger: NGXLogger
  ) {
    this.environmentsInfo = this.sessionStorageService.get<EnvironmentsInfo>(
      KEY_ENVIRONMENTS_INFO
    );
    this.sessionVerinfo = this.sessionStorageService.get<VersionInfo2Response>(
      KEY_VER_INFO
    );
  }

  ngOnInit() {
    this.loginResSubscription = this.store
      .pipe(
        select(AppStore.AccountSelector.AuthenticationSelector.loginRes),
        tap(loginRes => {
          if (!loginRes) {
            this.onCancel();
          }
          this.loginRes = loginRes;
        })
      )
      .subscribe();

    this.onSearch(this.data.keyword);

    this.presence$ = this.store.pipe(
      select(AppStore.MessengerSelector.StatusSelector.selectAllStatusBulkInfo)
    );
  }

  ngOnDestroy(): void {
    if (!!this.searchSubscription) {
      this.searchSubscription.unsubscribe();
    }
    if (!!this.loginResSubscription) {
      this.loginResSubscription.unsubscribe();
    }
  }

  onReSearch(searchWord: string) {
    this.pageCurrent = 1;

    this.onSearch(searchWord);
  }

  onSearch(searchWord: string) {
    this.currentSearchWord = this.data.keyword;

    if (searchWord.trim().length > 0) {
      this.searchingProcessing = true;
      const searchUserInfos: UserInfoSS[] = [];

      this.searchSubscription = this.queryProtocolService
        .deptUser({
          divCd: 'INT_SRCH',
          companyCode: this.loginRes.companyCode,
          searchRange: DeptSearchType.All,
          search: searchWord.trim(),
          senderCompanyCode: this.loginRes.companyCode,
          senderEmployeeType: this.loginRes.userInfo.employeeType,
          pageCurrent: this.pageCurrent,
          pageListCount: this.pageListCount
        })
        .pipe(
          map(res => {
            switch (res.SSVC_TYPE) {
              case SSVC_TYPE_QUERY_DEPT_USER_DATA:
                const userInfos = (res as DeptUserData).userInfos;
                searchUserInfos.push(...userInfos);
                break;
              case SSVC_TYPE_QUERY_DEPT_USER_RES:
                {
                  const response = res as DeptUserResponse;

                  // 검색 결과 처리.
                  this.searchUserInfos = searchUserInfos;

                  this.totalCount = response.pageTotalCount;
                  this.pageCurrent = response.pageCurrent;
                  this.pageListCount = response.pageListCount;
                  this.searchingProcessing = false;

                  // 검색 결과에 따른 프레즌스 조회.
                  if (searchUserInfos.length > 0) {
                    this.store.dispatch(
                      StatusStore.bulkInfo({
                        divCd: 'INT_SRCH',
                        userSeqs: this.searchUserInfos.map(user => user.seq)
                      })
                    );
                  }

                  console.log(this.searchUserInfos);
                }
                break;
            }
          }),
          catchError(error => {
            this.searchingProcessing = false;
            return of(this.logger.error(error));
          })
        )
        .subscribe();
    } else {
      // clear list.
      this.searchingProcessing = false;
      this.searchUserInfos = [];
    }
  }

  onCancel(): void {
    this.dialogRef.close({});
  }

  onChangePage(event: PageEvent) {
    this.pageCurrent = event.pageIndex + 1;
    this.pageListCount = event.pageSize;

    this.onSearch(this.currentSearchWord);
  }

  onClickOpenProfile(userSeq: number) {
    if (!userSeq || userSeq < 0) {
      return;
    }

    this.daesangProtocolService
      .dataUserDaesang({
        divCd: 'OPENPROF',
        seq: userSeq,
        senderCompanyCode: this.loginRes.userInfo.companyCode,
        senderEmployeeType: this.loginRes.userInfo.employeeType
      })
      .pipe(
        take(1),
        map(async res => {
          if (!!res && !!res.userInfo) {
            const result = await this.dialogService.open<
              ProfileDialogComponent,
              ProfileDialogData,
              ProfileDialogResult
            >(ProfileDialogComponent, {
              data: {
                userInfo: res.userInfo
              }
            });

            if (!!result) {
              if (!!result.closeEvent && result.closeEvent === 'CHAT') {
                this.onCancel();
              }
            }
          }
        })
      )
      .subscribe();
  }
}
