import {
  Component,
  OnInit,
  OnDestroy,
  Output,
  EventEmitter
} from '@angular/core';
import { Subscription } from 'rxjs';
import { Store, select } from '@ngrx/store';
import { tap, map } from 'rxjs/operators';

import * as AppStore from '@app/store';
import * as SyncStore from '@app/store/messenger/sync';
import * as RoomStore from '@app/store/messenger/room';

import { UserInfo } from '@ucap-webmessenger/protocol-room';
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import { KEY_VER_INFO } from '@app/types/ver-info.type';
import { DialogService } from '@ucap-webmessenger/ui';
import {
  SelectGroupDialogComponent,
  SelectGroupDialogResult,
  SelectGroupDialogData
} from '../../dialogs/group/select-group.dialog.component';
import { GroupDetailData } from '@ucap-webmessenger/protocol-sync';
import {
  CreateChatDialogComponent,
  CreateChatDialogResult,
  CreateChatDialogData
} from '../../dialogs/chat/create-chat.dialog.component';
import { UserSelectDialogType } from '@app/types';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import { KEY_LOGIN_RES_INFO } from '@app/types/login-res-info.type';

@Component({
  selector: 'app-layout-chat-right-drawer-room-user-list',
  templateUrl: './room-user-list.component.html',
  styleUrls: ['./room-user-list.component.scss']
})
export class RoomUserListComponent implements OnInit, OnDestroy {
  @Output()
  openProfile = new EventEmitter<UserInfo>();

  userInfoList: UserInfo[];
  userInfoListSubscription: Subscription;

  loginRes: LoginResponse;
  sessionVerinfo: VersionInfo2Response;

  constructor(
    private store: Store<any>,
    private sessionStorageService: SessionStorageService,
    private dialogService: DialogService
  ) {
    this.loginRes = this.sessionStorageService.get<LoginResponse>(
      KEY_LOGIN_RES_INFO
    );
    this.sessionVerinfo = this.sessionStorageService.get<VersionInfo2Response>(
      KEY_VER_INFO
    );
  }

  ngOnInit() {
    this.userInfoListSubscription = this.store
      .pipe(
        select(AppStore.MessengerSelector.RoomSelector.selectUserinfolist),
        tap(userInfoList => {
          this.userInfoList = userInfoList;
        })
      )
      .subscribe();
  }

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

  getStatusBulkInfo(buddy: UserInfo) {
    return this.store.pipe(
      select(
        AppStore.MessengerSelector.StatusSelector.selectEntitiesStatusBulkInfo
      ),
      map(statusBulkInfo =>
        !!statusBulkInfo ? statusBulkInfo[buddy.seq] : undefined
      )
    );
  }

  onClickOpenProfile(userInfo: UserInfo) {
    this.openProfile.emit(userInfo);
  }

  async onClickAddMember() {
    const result = await this.dialogService.open<
      CreateChatDialogComponent,
      CreateChatDialogData,
      CreateChatDialogResult
    >(CreateChatDialogComponent, {
      width: '600px',
      data: {
        type: UserSelectDialogType.EditChatMember,
        title: 'Edit Chat Member',
        curRoomUser: this.userInfoList.filter(
          user => user.seq !== this.loginRes.userSeq
        )
      }
    });

    if (!!result && !!result.choice && result.choice) {
      const userSeqs: number[] = this.userInfoList.map(
        userInfo => userInfo.seq
      );
      if (!!result.selectedUserList && result.selectedUserList.length > 0) {
        result.selectedUserList.forEach(user => {
          if (userSeqs.indexOf(user.seq) < 0) {
            userSeqs.push(user.seq);
          }
        });
      }

      if (userSeqs.length > 0) {
        // include me
        userSeqs.push(this.loginRes.userSeq);

        this.store.dispatch(
          RoomStore.inviteOrOpen({
            req: {
              divCd: 'Invite',
              userSeqs
            }
          })
        );
      }
    }
  }

  async onClickAddGroup() {
    const result = await this.dialogService.open<
      SelectGroupDialogComponent,
      SelectGroupDialogData,
      SelectGroupDialogResult
    >(SelectGroupDialogComponent, {
      width: '600px',
      data: {
        title: 'Group Select'
      }
    });

    if (!!result && !!result.choice && result.choice) {
      if (!!result.group) {
        const oldGroup: GroupDetailData = result.group;
        const trgtUserSeq: number[] = [];
        result.group.userSeqs.map(seq => trgtUserSeq.push(seq));
        this.userInfoList
          .filter(v => result.group.userSeqs.indexOf(v.seq) < 0)
          .forEach(user => {
            trgtUserSeq.push(user.seq);
          });

        this.store.dispatch(
          SyncStore.updateGroupMember({
            oldGroup,
            trgtUserSeq
          })
        );
      }
    }
  }
}
