import {
  Component,
  ViewChild,
  OnInit,
  ChangeDetectorRef,
  Input,
  OnDestroy,
  ChangeDetectionStrategy
} from '@angular/core';
import { MatTableDataSource } from '@angular/material/table';
import { SelectionModel } from '@angular/cdk/collections';
import { MatSort } from '@angular/material/sort';
import { Subject, of } from 'rxjs';
import { map, takeUntil, take, catchError } from 'rxjs/operators';
import {
  DeptInfo,
  DeptSearchType,
  DeptUserRequest,
  UserInfoSS,
  AuthResponse
} from '@ucap/protocol-query';
import {
  DepartmentSelector,
  PresenceActions
} from '@ucap/ng-store-organization';
import { select, Store } from '@ngrx/store';
import { QueryProtocolService } from '@ucap/ng-protocol-query';
import {
  LoginSelector,
  AuthorizationSelector,
  ConfigurationSelector
} from '@ucap/ng-store-authentication';
import { LoginResponse } from '@ucap/protocol-authentication';
import {
  FixedSizeVirtualScrollStrategy,
  VIRTUAL_SCROLL_STRATEGY,
  CdkVirtualScrollViewport
} from '@angular/cdk/scrolling';
import { VersionInfo2Response } from '@ucap/api-public';
import { PerfectScrollbarDirective } from 'ngx-perfect-scrollbar';

export class DepartmentUserVirtualScrollStrategy extends FixedSizeVirtualScrollStrategy {
  constructor() {
    super(184, 150, 200);
  }
}

@Component({
  selector: 'app-organization-detail-table',
  templateUrl: './detail-table.component.html',
  styleUrls: ['./detail-table.component.scss'],
  providers: [
    {
      provide: VIRTUAL_SCROLL_STRATEGY,
      useClass: DepartmentUserVirtualScrollStrategy
    }
  ],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class DetailTableComponent implements OnInit, OnDestroy {
  @Input()
  set searchObj(obj: {
    isShowSearch: boolean;
    companyCode: string;
    searchWord: string;
  }) {
    this._searchObj = obj;
    if (obj.isShowSearch && obj.searchWord.localeCompare('') !== 0) {
      this.onOrganizationTenantSearch(obj);
    } else {
      this._searchObj.isShowSearch = false;
      this.searchUserList = [];
      this.changeDetectorRef.detectChanges();
    }
  }

  get searchObj() {
    return this._searchObj;
  }
  // tslint:disable-next-line: variable-name
  _searchObj: any;

  @Input()
  set deptSeq(deptSeq: string) {
    this._deptSeq = deptSeq;
    this.getSelectedDeptInfo();
  }
  get deptSeq(): string {
    return this._deptSeq;
  }
  // tslint:disable-next-line: variable-name
  _deptSeq: string;

  versionInfo2Res: VersionInfo2Response;
  loginRes: LoginResponse;
  authRes: AuthResponse;

  defaultProfileImage = 'assets/images/ico/img_nophoto.svg';

  departmentInfoList: DeptInfo[];
  selectedDeptInfo: DeptInfo;

  departmentUserListProcessing = false;
  departmentUserList: UserInfoSS[] = [];
  searchUserList: UserInfoSS[] = [];

  selectedUserList: UserInfoSS[] = [];

  @ViewChild('cvsvList', { static: false })
  cvsvList: CdkVirtualScrollViewport;

  @ViewChild(PerfectScrollbarDirective, { static: false })
  psDirectiveRef?: PerfectScrollbarDirective;

  private ngOnDestroySubject: Subject<boolean>;

  constructor(
    private store: Store<any>,
    private queryProtocolService: QueryProtocolService,
    private changeDetectorRef: ChangeDetectorRef
  ) {}

  ngOnInit() {
    this.ngOnDestroySubject = new Subject<boolean>();

    this.store
      .pipe(
        takeUntil(this.ngOnDestroySubject),
        select(ConfigurationSelector.versionInfo2Response)
      )
      .subscribe((versionInfo2Res) => {
        this.versionInfo2Res = versionInfo2Res;
      });

    this.store
      .pipe(takeUntil(this.ngOnDestroySubject), select(LoginSelector.loginRes))
      .subscribe((loginRes) => {
        this.loginRes = loginRes;
      });

    this.store
      .pipe(
        takeUntil(this.ngOnDestroySubject),
        select(AuthorizationSelector.authResponse)
      )
      .subscribe((authRes) => {
        this.authRes = authRes;
      });

    this.store
      .pipe(
        takeUntil(this.ngOnDestroySubject),
        select(DepartmentSelector.departmentInfoList)
      )
      .subscribe((departmentInfoList) => {
        this.departmentInfoList = departmentInfoList;
        this.getSelectedDeptInfo();
      });
  }

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

  getSelectedDeptInfo() {
    if (
      !!this.deptSeq &&
      !!this.departmentInfoList &&
      this.departmentInfoList.length > 0
    ) {
      const existDept = this.departmentInfoList.some((deptInfo) => {
        if (Number(deptInfo.seq + '') === Number(this.deptSeq + '')) {
          this.selectedDeptInfo = deptInfo;
          return true;
        }
      });

      if (!!existDept && !!this.loginRes) {
        this.departmentUserListProcessing = true;
        const req: DeptUserRequest = {
          divCd: 'ORG',
          companyCode: this.loginRes.companyCode,
          seq: Number(this.deptSeq),
          search: '',
          searchRange: DeptSearchType.All,
          senderCompanyCode: this.loginRes.companyCode,
          senderEmployeeType: this.loginRes.userInfo.employeeType
        };
        this.queryProtocolService
          .deptUser(req)
          .pipe(
            take(1),
            map((res) => {
              this.departmentUserList = res.userInfos;
              this.departmentUserListProcessing = false;

              if (!!this.cvsvList) {
                this.cvsvList.checkViewportSize();
              }
              if (!!this.psDirectiveRef) {
                this.psDirectiveRef.update();
              }

              this.changeDetectorRef.detectChanges();
            }),
            catchError((error) => {
              this.departmentUserListProcessing = false;
              return of(error);
            })
          )
          .subscribe();
      }

      this.changeDetectorRef.detectChanges();
    }
  }

  onOrganizationTenantSearch(obj: {
    isShowSearch: boolean;
    companyCode: string;
    searchWord: string;
  }) {
    this.departmentUserListProcessing = true;

    this.queryProtocolService
      .deptUser({
        divCd: 'ORGS',
        companyCode: this._searchObj.companyCode,
        searchRange: DeptSearchType.All,
        search: this._searchObj.searchWord,
        senderCompanyCode: this.loginRes.userInfo.companyCode,
        senderEmployeeType: this.loginRes.userInfo.employeeType
      })
      .pipe(
        map((resObj) => {
          // 검색 결과 처리.
          this.searchUserList = resObj.userInfos.sort((a, b) =>
            a.name < b.name ? -1 : a.name > b.name ? 1 : 0
          );
          this.changeDetectorRef.detectChanges();
          this.departmentUserListProcessing = false;

          // 검색 결과에 따른 프레즌스 조회.
          const userSeqList: string[] = [];
          this.searchUserList.map((user) => userSeqList.push(user.seq));

          if (userSeqList.length > 0) {
            this.store.dispatch(
              PresenceActions.bulkInfo({
                divCd: 'orgSrch',
                userSeqs: userSeqList
              })
            );
          }
        }),
        catchError((error) => {
          this.departmentUserListProcessing = false;
          return of(error);
        })
      )
      .subscribe();
  }

  /** 전체선택 체크여부  */
  getCheckedAllUser() {
    if (!this.loginRes) {
      return false;
    }

    const compareList: UserInfoSS[] = !!this.searchObj.isShowSearch
      ? this.searchUserList
      : this.departmentUserList;
    if (
      !compareList ||
      compareList.length === 0 ||
      compareList.filter((item) => item.seq !== this.loginRes.userSeq)
        .length === 0 ||
      compareList
        .filter((item) => item.seq !== this.loginRes.userSeq)
        .filter(
          (item) =>
            !(
              this.selectedUserList.filter((user) => user.seq === item.seq)
                .length > 0
            )
        ).length > 0
    ) {
      return false;
    } else {
      return true;
    }
  }
  /** 전체선택 이벤트 */
  onCheckAllUser(value: boolean) {
    if (!this.loginRes) {
      return false;
    }

    const trgtUserList = !!this.searchObj.isShowSearch
      ? this.searchUserList
      : this.departmentUserList;

    if (!!value) {
      this.selectedUserList = trgtUserList.slice();
    } else {
      this.selectedUserList = [];
    }

    this.changeDetectorRef.detectChanges();
  }
  /** 개별 체크여부 */
  getCheckedUser(userInfo: UserInfoSS) {
    if (!!this.selectedUserList && this.selectedUserList.length > 0) {
      return (
        this.selectedUserList.filter((item) => item.seq === userInfo.seq)
          .length > 0
      );
    }
    return false;
  }
  /** 개별선택(토글) 이벤트 */
  onToggleUser(param: { isChecked: boolean; userInfo: UserInfoSS }) {
    if (!this.loginRes || param.userInfo.seq === this.loginRes.userSeq) {
      return;
    }

    if (
      !this.selectedUserList.some((user) => user.seq === param.userInfo.seq)
    ) {
      this.selectedUserList = [...this.selectedUserList, param.userInfo];
    } else {
      this.selectedUserList = this.selectedUserList.filter(
        (item) => item.seq !== param.userInfo.seq
      );
    }
    this.changeDetectorRef.detectChanges();
  }

  onClickDeleteUserChips(userInfo: UserInfoSS) {
    this.selectedUserList = this.selectedUserList.filter(
      (item) => item.seq !== userInfo.seq
    );
    this.changeDetectorRef.detectChanges();
  }

  onOpenProfile(userInfo: UserInfoSS): void {
    alert('Open Profile');
  }

  onClickAddGroup(): void {
    alert('onClickAddGroup');
  }
  onClickChatOpen(): void {
    alert('onClickChatOpen');
  }
  onClickMessage(): void {
    alert('onClickMessage');
  }
  onClickCall(): void {
    alert('onClickCall');
  }
  onClickConference(): void {
    alert('onClickConference');
  }
}
