import { UserSelectDialogType } from './../../../types/userselect.dialog.type';
import {
  Component,
  OnInit,
  Output,
  EventEmitter,
  ViewChildren,
  QueryList,
  ElementRef,
  OnDestroy,
  ViewChild
} from '@angular/core';
import { NGXLogger } from 'ngx-logger';
import { ucapAnimations, DialogService } from '@ucap-webmessenger/ui';
import {
  CreateChatDialogComponent,
  CreateChatDialogData,
  CreateChatDialogResult
} from '@app/layouts/messenger/dialogs/chat/create-chat.dialog.component';
import { Subscription, merge } from 'rxjs';
import { Store, select } from '@ngrx/store';

import * as AppStore from '@app/store';
import * as ChatStore from '@app/store/messenger/chat';
import * as MessageStore from '@app/store/messenger/message';
import * as SyncStore from '@app/store/messenger/sync';
import { UserInfo } from '@ucap-webmessenger/protocol-sync';
import {
  UserInfoSS,
  UserInfoF,
  UserInfoDN
} from '@ucap-webmessenger/protocol-query';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import { OpenProfileOptions } from '@ucap-webmessenger/protocol-buddy';
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
import { MessageType } from '@ucap-webmessenger/api-message';
import { tap } from 'rxjs/operators';
import {
  MessageWriteDialogComponent,
  MessageWriteDialogResult,
  MessageWriteDialogData
} from '../dialogs/message/message-write.dialog.component';
import {
  EnvironmentsInfo,
  KEY_ENVIRONMENTS_INFO,
  KEY_VER_INFO,
  MainMenu
} from '@app/types';
import { MessageBoxComponent } from './left-sidenav/message.component';
import { environment } from '../../../../environments/environment';
import { TranslateService } from '@ngx-translate/core';

@Component({
  selector: 'app-layout-messenger-left-side',
  templateUrl: './left-side.component.html',
  styleUrls: ['./left-side.component.scss'],
  animations: ucapAnimations
})
export class LeftSideComponent implements OnInit, OnDestroy {
  @Output()
  openProfile = new EventEmitter<{
    userSeq: number;
    openProfileOptions?: OpenProfileOptions;
  }>();
  @Output()
  sendCall = new EventEmitter<string>();
  @Output()
  sendSms = new EventEmitter<string>();

  @ViewChildren('tabs') tabs: QueryList<ElementRef<HTMLDivElement>>;
  currentTabLable: string;

  @ViewChild('messageBoxComponent', { static: false })
  messageBoxComponent: MessageBoxComponent;

  onLangChangeSubscription: Subscription;

  /** 조직도에서 부서원 선택 */
  selectedUserList: (UserInfo | UserInfoSS | UserInfoF | UserInfoDN)[] = [];

  /** FAB */
  fabButtonShow = true;
  fabButtons: { icon: string; tooltip?: string; divisionType?: string }[];

  MainMenu = MainMenu;

  sessionVerinfo: VersionInfo2Response;
  environmentsInfo: EnvironmentsInfo;
  loginRes: LoginResponse;
  loginResSubscription: Subscription;

  constructor(
    private store: Store<any>,
    public elementRef: ElementRef<HTMLElement>,
    private dialogService: DialogService,
    private sessionStorageService: SessionStorageService,
    private translateService: TranslateService,
    private logger: NGXLogger
  ) {
    this.sessionVerinfo = this.sessionStorageService.get<VersionInfo2Response>(
      KEY_VER_INFO
    );

    this.environmentsInfo = this.sessionStorageService.get<EnvironmentsInfo>(
      KEY_ENVIRONMENTS_INFO
    );
  }

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

    this.setFabInitial(MainMenu.Group);
    this.currentTabLable = MainMenu.Group;

    this.onLangChangeSubscription = merge(
      this.translateService.onLangChange,
      this.translateService.onDefaultLangChange,
      this.translateService.onTranslationChange
    ).subscribe(() => {
      this.setFabInitial(this.currentTabLable);
    });

    this.loginResSubscription = this.store
      .pipe(
        select(AppStore.MessengerSelector.SettingsSelector.gnbMenuIndex),
        tap(menuIndex => {
          this.currentTabLable = menuIndex;
          this.setFabInitial(menuIndex);
        })
      )
      .subscribe();
  }

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

  async onClickNewChat(type: string = 'NORMAL') {
    const result = await this.dialogService.open<
      CreateChatDialogComponent,
      CreateChatDialogData,
      CreateChatDialogResult
    >(CreateChatDialogComponent, {
      width: '600px',
      data: {
        type: UserSelectDialogType.NewChat,
        title:
          type === 'TIMER'
            ? this.translateService.instant('chat.newTimerChat')
            : this.translateService.instant('chat.newChat')
      }
    });

    if (!!result && !!result.choice && result.choice) {
      if (!!result.selectedUserList && result.selectedUserList.length > 0) {
        const userSeqs: number[] = [];
        result.selectedUserList.map(user => userSeqs.push(user.seq));

        if (type === 'NORMAL') {
          this.store.dispatch(ChatStore.openRoom({ userSeqList: userSeqs }));
        } else if (type === 'TIMER') {
          this.store.dispatch(
            ChatStore.openRoom({ userSeqList: userSeqs, isTimeRoom: true })
          );
        }
      }
    }
  }

  async onClickNewGroupAndMember() {
    const result = await this.dialogService.open<
      CreateChatDialogComponent,
      CreateChatDialogData,
      CreateChatDialogResult
    >(CreateChatDialogComponent, {
      width: '600px',
      data: {
        type: UserSelectDialogType.NewGroup,
        title: this.translateService.instant('group.addNew')
      }
    });

    if (!!result && !!result.choice && result.choice) {
      if (
        !!result.selectedUserList &&
        // result.selectedUserList.length > 0 &&
        result.groupName.trim().length > 0
      ) {
        const userSeqs: number[] = [];
        result.selectedUserList.map(user => userSeqs.push(user.seq));

        this.store.dispatch(
          SyncStore.createGroupAndBuddy({
            groupName: result.groupName,
            trgtUserSeq: userSeqs
          })
        );
      }
    }
  }

  async onClickNewMessage() {
    const result = await this.dialogService.open<
      MessageWriteDialogComponent,
      MessageWriteDialogData,
      MessageWriteDialogResult
    >(MessageWriteDialogComponent, {
      width: '600px',
      height: '600px',
      disableClose: true,
      hasBackdrop: false,
      data: {
        loginRes: this.loginRes,
        environmentsInfo: this.environmentsInfo
      }
    });

    if (!!result && !!result.sendFlag && result.sendFlag) {
      if (
        this.currentTabLable === MainMenu.Message &&
        !!this.messageBoxComponent
      ) {
        const type = result.sendType || MessageType.Send;
        switch (type) {
          case MessageType.Send:
            this.messageBoxComponent.onSelectedIndexChange(1);
            this.messageBoxComponent.onSelectedIndexTab(1);
            break;
          case MessageType.Reservation:
            this.messageBoxComponent.onSelectedIndexChange(2);
            this.messageBoxComponent.onSelectedIndexTab(2);
            break;
        }
      }
    }
  }

  onClickOpenProfile(params: {
    userSeq: number;
    openProfileOptions?: OpenProfileOptions;
  }) {
    this.openProfile.emit({
      userSeq: params.userSeq,
      openProfileOptions: params.openProfileOptions
    });
  }
  onClickSendClickToCall(calleeNumber: string) {
    this.sendCall.emit(calleeNumber);
  }
  onClickSendSms(calleeNumber: string) {
    this.sendSms.emit(calleeNumber);
  }

  setFabInitial(type: string) {
    switch (type) {
      case MainMenu.Group:
        {
          this.fabButtonShow = true;
          this.fabButtons = [
            {
              icon: 'add',
              tooltip: this.translateService.instant('group.addNew'),
              divisionType: 'GROUP_NEW_ADD'
            }
          ];
        }
        break;
      case MainMenu.Chat:
        {
          this.fabButtonShow = true;
          this.fabButtons = [
            {
              icon: 'chat',
              tooltip: this.translateService.instant('chat.newChat'),
              divisionType: 'CAHT_NEW_ADD'
            }
          ];

          if (environment.productConfig.CommonSetting.useTimerRoom) {
            this.fabButtons.push({
              icon: 'timer',
              tooltip: this.translateService.instant('chat.newTimerChat'),
              divisionType: 'CHAT_NEW_TIMER_ADD'
            });
          }
        }
        break;
      case MainMenu.Organization:
        {
          this.fabButtonShow = false;
        }
        break;
      case MainMenu.Message:
        {
          this.fabButtonShow = true;
          this.fabButtons = [
            {
              icon: 'add',
              tooltip: this.translateService.instant('message.new'),
              divisionType: 'MESSAGE_NEW'
            }
          ];
        }
        break;
      case MainMenu.Call:
        {
          this.fabButtonShow = false;
        }
        break;

      default: {
        this.fabButtonShow = false;
      }
    }
  }

  onCheckAllUser(params: {
    isChecked: boolean;
    userInfos: (UserInfo | UserInfoSS | UserInfoF | UserInfoDN)[];
  }) {
    params.userInfos.forEach(userInfo => {
      if (params.isChecked) {
        if (
          this.selectedUserList.filter(user => user.seq === userInfo.seq)
            .length === 0
        ) {
          this.selectedUserList = [...this.selectedUserList, userInfo];
        }
      } else {
        this.selectedUserList = this.selectedUserList.filter(
          user => user.seq !== userInfo.seq
        );
      }
    });
  }

  /** 조직도>부서원 :: 리스트의 checkbox 의 이벤트를 받아 선택된 유저리스트를 수집. */
  onCheckUser(params: {
    isChecked: boolean;
    userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN;
  }) {
    if (params.isChecked) {
      if (
        params.userInfo &&
        this.selectedUserList.filter(user => user.seq === params.userInfo.seq)
          .length === 0
      ) {
        this.selectedUserList = [...this.selectedUserList, params.userInfo];
      }
    } else {
      this.selectedUserList = this.selectedUserList.filter(
        user => user.seq !== params.userInfo.seq
      );
    }
  }
  onToggleUser(userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN) {
    if (
      this.selectedUserList.filter(user => user.seq === userInfo.seq).length ===
      0
    ) {
      this.selectedUserList = [...this.selectedUserList, userInfo];
    } else {
      this.selectedUserList = this.selectedUserList.filter(
        item => item.seq !== userInfo.seq
      );
    }
  }
  onResetSelectedUserList(
    selectedUserList: (UserInfo | UserInfoSS | UserInfoF | UserInfoDN)[]
  ) {
    this.selectedUserList = selectedUserList;
  }

  /** FAB */
  onClickFab(params: { btn: any }) {
    const btn = params.btn as {
      icon: string;
      tooltip?: string;
      divisionType?: string;
    };

    switch (btn.divisionType) {
      case 'GROUP_NEW_ADD':
        {
          this.onClickNewGroupAndMember();
        }
        break;

      case 'CAHT_NEW_ADD':
        {
          this.onClickNewChat('NORMAL');
        }
        break;
      case 'CHAT_NEW_TIMER_ADD':
        {
          if (environment.productConfig.CommonSetting.useTimerRoom) {
            this.onClickNewChat('TIMER');
          }
        }
        break;

      case 'MESSAGE_NEW':
        {
          this.onClickNewMessage();
        }
        break;
    }
  }

  getMessageUnreadCount(): void {
    this.store.dispatch(MessageStore.retrieveUnreadCount({}));
  }
}
