import { Component, OnInit, Inject, ViewChild } from '@angular/core';
import {
  MatDialogRef,
  MAT_DIALOG_DATA,
  MatSelectionList,
  MatSelectionListChange
} from '@angular/material';
import { Observable, combineLatest } from 'rxjs';
import { Store, select } from '@ngrx/store';
import { map, take } from 'rxjs/operators';

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

import {
  DialogService,
  ConfirmDialogComponent,
  ConfirmDialogData,
  ConfirmDialogResult
} from '@ucap-webmessenger/ui';
import { GroupDetailData, UserInfo } from '@ucap-webmessenger/protocol-sync';
import { environment } from '../../../../../environments/environment';
import { TranslateService } from '@ngx-translate/core';

export interface SelectGroupDialogData {
  title: string;
  ignoreGroup?: GroupDetailData[];
}

export interface SelectGroupDialogResult {
  choice: boolean;
  group?: GroupDetailData;
}

@Component({
  selector: 'app-layout-messenger-select-group',
  templateUrl: './select-group.dialog.component.html',
  styleUrls: ['./select-group.dialog.component.scss']
})
export class SelectGroupDialogComponent implements OnInit {
  constructor(
    public dialogRef: MatDialogRef<
      SelectGroupDialogData,
      SelectGroupDialogResult
    >,
    @Inject(MAT_DIALOG_DATA) public data: SelectGroupDialogData,
    private store: Store<any>,
    private dialogService: DialogService,
    private translateService: TranslateService
  ) {}

  @ViewChild('groups', { static: true }) groups: MatSelectionList;
  groupBuddyList$: Observable<
    { group: GroupDetailData; buddyList: UserInfo[] }[]
  >;
  selectedGroup: GroupDetailData;
  isShowAddGroupField = false;

  ngOnInit(): void {
    this.groups.selectionChange.subscribe((s: MatSelectionListChange) => {
      this.groups.deselectAll();
      s.option.selected = true;
      this.selectedGroup = s.option.value as GroupDetailData;
    });

    this.groupBuddyList$ = combineLatest([
      this.store.pipe(
        select(AppStore.MessengerSelector.SyncSelector.selectAllBuddy2)
      ),
      this.store.pipe(
        select(AppStore.MessengerSelector.SyncSelector.selectAllGroup2)
      )
    ]).pipe(
      map(([buddyList, groupList]) => {
        // sort..
        if (!!groupList && groupList.length > 0) {
          const tempOrderArr: GroupDetailData[] = [];
          let myDeptGroup: GroupDetailData;
          let defaultGroup: GroupDetailData;
          const normalGroup: GroupDetailData[] = [];

          groupList.forEach(group => {
            if (
              !!environment.productConfig.CommonSetting.useMyDeptGroup &&
              environment.productConfig.CommonSetting.myDeptGroupSeq ===
                group.seq
            ) {
              myDeptGroup = group;
            } else if (0 === group.seq) {
              defaultGroup = group;
            } else {
              normalGroup.push(group);
            }
          });

          if (!!myDeptGroup) {
            tempOrderArr.push(myDeptGroup);
          }

          tempOrderArr.push(
            ...normalGroup.sort((a, b) =>
              a.name < b.name ? -1 : a.name > b.name ? 1 : 0
            )
          );

          if (!!defaultGroup) {
            tempOrderArr.push(defaultGroup);
          }

          groupList = tempOrderArr;
        }

        /** 수정불가 그룹 */
        let fixedGroupSeqs: number[];
        if (!!environment.productConfig.CommonSetting.fixedGroupSeqs) {
          fixedGroupSeqs =
            environment.productConfig.CommonSetting.fixedGroupSeqs;
        }

        const groupBuddyList: {
          group: GroupDetailData;
          buddyList: UserInfo[];
        }[] = [];
        for (const group of groupList) {
          /** 수정불가 그룹 필터링. */
          if (!!fixedGroupSeqs && fixedGroupSeqs.length > 0) {
            if (fixedGroupSeqs.indexOf(group.seq) > -1) {
              continue;
            }
          }

          /** 선택 무시 그룹 필터링. */
          if (!!this.data.ignoreGroup && this.data.ignoreGroup.length > 0) {
            if (
              this.data.ignoreGroup.filter(
                groupDetail => groupDetail.seq === group.seq
              ).length > 0
            ) {
              continue;
            }
          }

          groupBuddyList.push({
            group,
            buddyList: buddyList.filter(buddy => {
              return group.userSeqs.indexOf(buddy.seq) > -1;
            })
          });
        }

        return groupBuddyList;
      })
    );
  }

  async onClickAddGroup(groupName: string) {
    const result = await this.dialogService.open<
      ConfirmDialogComponent,
      ConfirmDialogData,
      ConfirmDialogResult
    >(ConfirmDialogComponent, {
      width: '300px',
      data: {
        title: this.translateService.instant('group.addNew'),
        html: this.translateService.instant('group.confirmAddNewWith', {
          nameOfGroup: groupName
        })
      }
    });

    if (!!result && !!result.choice && result.choice) {
      if (groupName.trim().length > 0) {
        this.store.dispatch(
          SyncStore.createGroup({
            groupName: groupName.trim()
          })
        );

        this.onClickAddGroupCancel();
      }
    }
  }
  onClickAddGroupCancel() {
    this.isShowAddGroupField = false;
  }

  onClickChoice(choice: boolean): void {
    this.dialogRef.close({
      choice,
      group: this.selectedGroup
    });
  }

  getDisabled(groupBuddyList: {
    group: GroupDetailData;
    buddyList: UserInfo[];
  }): boolean {
    if (!!this.data.ignoreGroup && this.data.ignoreGroup.length > 0) {
      return (
        this.data.ignoreGroup.filter(
          groupDetail => groupDetail.seq === groupBuddyList.group.seq
        ).length > 0
      );
    }
    return false;
  }
}
