import { Subject, of } from 'rxjs';

import {
  Component,
  OnInit,
  OnDestroy,
  ChangeDetectionStrategy,
  ChangeDetectorRef,
  Inject,
  Input,
  ComponentFactoryResolver,
  ViewChild,
  ViewContainerRef,
  ComponentRef
} from '@angular/core';

import { Store } from '@ngrx/store';

import {
  MatDialogRef,
  MAT_DIALOG_DATA,
  MatDialog
} from '@angular/material/dialog';

import { UserInfo, GroupDetailData } from '@ucap/protocol-sync';
import { UserInfoSS, UserInfoF, UserInfoDN } from '@ucap/protocol-query';
import { UserInfo as RoomUserInfo } from '@ucap/protocol-room';
import { MatStepper } from '@angular/material/stepper';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { I18nService } from '@ucap/ng-i18n';
import { GroupActions } from '@ucap/ng-store-group';
import {
  AlertDialogComponent,
  AlertDialogData,
  AlertDialogResult,
  ConfirmDialogComponent,
  ConfirmDialogResult,
  ConfirmDialogData
} from '@ucap/ng-ui';
import { SelectUserSectionComponent } from '../components/select-user.section.component';
import { take, map, catchError } from 'rxjs/operators';
import { SelectGroupSectionComponent } from '../components/select-group.section.component';
import { SelectUserDialogType, GroupUserDialaogType } from '@app/types';

export type UserInfoTypes =
  | UserInfo
  | UserInfoSS
  | UserInfoF
  | UserInfoDN
  | RoomUserInfo;

export interface ManageDialogData {
  title: string;
  groupBuddyList?: { group: GroupDetailData; buddyList: UserInfo[] };
}
export interface ManageDialogResult {
  type: GroupUserDialaogType;
  groupName: string;
  group?: GroupDetailData;
  selelctUserList?: UserInfoTypes[];
  selectGroupList?: GroupDetailData[];
}

@Component({
  selector: 'app-dialog-group-manage',
  templateUrl: './manage.dialog.component.html',
  styleUrls: ['./manage.dialog.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class ManageDialogComponent implements OnInit, OnDestroy {
  constructor(
    public dialogRef: MatDialogRef<ManageDialogData, ManageDialogResult>,
    @Inject(MAT_DIALOG_DATA) public data: ManageDialogData,
    private changeDetectorRef: ChangeDetectorRef,
    private store: Store<any>,
    private formBuilder: FormBuilder,
    private i18nService: I18nService,
    public dialog: MatDialog,
    private cfResolver: ComponentFactoryResolver
  ) {}

  @ViewChild('dialogContainer', { static: true, read: ViewContainerRef })
  dialogContainer: ViewContainerRef;

  componentRef: ComponentRef<any>;
  private ngOnDestroySubject: Subject<void>;
  currentType: GroupUserDialaogType;
  SelectUserDialogType = SelectUserDialogType;
  GroupUserDialaogType = GroupUserDialaogType;

  currentStep = 0;
  groupName = '';

  delteUserList: UserInfoTypes[] = [];
  selectedUserList: UserInfoTypes[] = [];
  selectedGroupList: GroupDetailData[] = [];

  ngOnInit(): void {
    this.ngOnDestroySubject = new Subject();
    // this.selectedUserList = this.data.groupBuddyList.buddyList;
  }

  ngOnDestroy(): void {
    if (!!this.ngOnDestroySubject) {
      this.ngOnDestroySubject.complete();
    }
  }

  onClosed(event: MouseEvent): void {
    this.dialogRef.close();
  }

  onDelete(stepper: MatStepper) {
    if (
      !!this.delteUserList &&
      this.delteUserList.length > 0 &&
      this.currentStep === 0
    ) {
      let titleStr = '';
      this.delteUserList.forEach((user, idx) => {
        let userTitle = user.name + ' ' + user.grade;
        if (idx < this.delteUserList.length) {
          userTitle = userTitle + ', ';
        }
        titleStr = titleStr.concat('', userTitle);
      });
      const dialogRef = this.dialog.open<
        ConfirmDialogComponent,
        ConfirmDialogData,
        ConfirmDialogResult
      >(ConfirmDialogComponent, {
        data: {
          title: '동료 삭제',
          html: titleStr + '을 삭제하시겠습니까?'
        }
      });
      dialogRef
        .afterClosed()
        .pipe(
          take(1),
          map((result) => {
            if (!!result && result.choice) {
              const trgtUserSeq: string[] = [];

              this.delteUserList.forEach((userIfno) => {
                const tempSeq = this.data.groupBuddyList.group.userSeqs.filter(
                  (seq) => seq === userIfno.seq
                );

                trgtUserSeq.push(tempSeq[0]);
              });

              console.log(trgtUserSeq);

              this.store.dispatch(
                GroupActions.updateMember({
                  targetGroup: this.data.groupBuddyList.group,
                  targetUserSeqs: trgtUserSeq
                })
              );
              this.dialogRef.close();
            }
          }),
          catchError((err) => {
            return of(err);
          })
        )
        .subscribe();
    }
  }
  onUpdateMember(stepper: MatStepper, type: GroupUserDialaogType) {
    this.dialogContainer.clear();
    this.currentType = type;
    const isMemberMove = type === GroupUserDialaogType.Copy ? false : true;
    // const title = type === GroupUserDialaogType.Copy ? '멤버 복사' : '멤버 이동';

    const factory = this.cfResolver.resolveComponentFactory(
      SelectGroupSectionComponent
    );

    this.componentRef = this.dialogContainer.createComponent(factory);
    const cpInstance = this.componentRef.instance;
    // cpInstance.title = title;
    cpInstance.isMemberMove = isMemberMove;
    cpInstance.isDialog = true;
    cpInstance.checkable = true;
    cpInstance.curGroup = this.data.groupBuddyList.group;
    cpInstance.changeUserList.subscribe((val) => {
      this.selectedUserList = val;
    });
    cpInstance.changeGroupList.subscribe((groupList) => {
      this.selectedGroupList = groupList;
    });
    cpInstance.changeGroupName.subscribe((groupName) => {
      this.groupName = groupName;
    });
    this.currentStep++;
    stepper.next();
  }

  onAdd(stepper: MatStepper) {
    this.dialogContainer.clear();
    this.currentType = GroupUserDialaogType.Add;
    // this.selectedUserList = this.data.groupBuddyList.buddyList;

    const factory = this.cfResolver.resolveComponentFactory(
      SelectUserSectionComponent
    );

    this.componentRef = this.dialogContainer.createComponent(factory);
    const cpInstance = this.componentRef.instance;
    cpInstance.isDialog = true;
    cpInstance.checkable = true;
    cpInstance.selectedUserList = this.data.groupBuddyList.buddyList;
    cpInstance.isSelectionOff = false;
    cpInstance.changeUserList.subscribe((val) => {
      this.selectedUserList = val;
    });
    this.currentStep++;
    stepper.next();
  }

  onChangeUserList(selectedUserList: UserInfoTypes[]) {
    this.selectedUserList = selectedUserList;
  }

  onCnacel(stepper: MatStepper) {
    if (!!this.selectedUserList && this.selectedUserList.length > 0) {
      this.selectedUserList = [];
    }
    this.currentStep--;
    stepper.previous();
  }
  onConfirm(stepper: MatStepper) {
    switch (this.currentType) {
      case GroupUserDialaogType.Add:
        {
          if (!!this.selectedUserList && this.selectedUserList.length > 0) {
            this.doAction();
          }
        }
        break;
      case GroupUserDialaogType.Copy:
      case GroupUserDialaogType.Move:
        {
          if (!!this.selectedUserList && this.selectedUserList.length === 0) {
            this.dialog.open<
              AlertDialogComponent,
              AlertDialogData,
              AlertDialogResult
            >(AlertDialogComponent, {
              data: {
                title: 'Error',
                html: '선택된 유저가 없습니다.'
              }
            });

            return;
          }

          this.doAction();
        }
        break;
    }
  }

  doAction() {
    this.dialogContainer.clear();
    if (!!this.groupName && this.groupName.trim().localeCompare('') !== 0) {
      this.currentType = GroupUserDialaogType.Create;
    } else {
      this.groupName = undefined;
    }

    this.dialogRef.close({
      type: this.currentType,
      groupName: this.groupName,
      group: this.data.groupBuddyList.group,
      selelctUserList: this.selectedUserList,
      selectGroupList: this.selectedGroupList
    });
  }

  /** 개별 체크여부 */
  getCheckedUser(userInfo: UserInfoSS) {
    if (!!this.selectedUserList && this.selectedUserList.length > 0) {
      return (
        this.selectedUserList.filter(
          (item) => (item.seq as any) === (userInfo.seq as any)
        ).length > 0
      );
    }
    return false;
  }

  onToggleCheckForDelete(data: { checked: boolean; userInfo: UserInfoSS }) {
    if (data.checked) {
      this.delteUserList.push(data.userInfo);
    } else {
      const index = this.delteUserList.findIndex(
        (userInfo) => userInfo.seq === data.userInfo.seq
      );
      if (index > -1) {
        this.delteUserList.splice(index, 1);
      }
    }
    this.onToggleCheck(data);
  }
  onToggleCheck(data: { checked: boolean; userInfo: UserInfoSS }) {
    if (data.checked) {
      this.selectedUserList.push(data.userInfo);
    } else {
      const index = this.selectedUserList.findIndex(
        (userInfo) => userInfo.seq === data.userInfo.seq
      );
      if (index > -1) {
        this.selectedUserList.splice(index, 1);
      }
    }
  }

  onRemovedProfileSelection(userInfo: UserInfo) {
    const i = this.selectedUserList.findIndex(
      (u) => (u.seq as any) === (userInfo.seq as any)
    );

    if (-1 < i) {
      this.selectedUserList = this.selectedUserList.filter(
        (u) => (u.seq as any) !== (userInfo.seq as any)
      );
    }
  }

  removableForSelection = (userInfo: UserInfo) => {
    return true;
  };

  colorForSelection = (userInfo: UserInfo) => {
    return 'accent';
  };
}
