import { Component, ChangeDetectorRef, OnInit, OnDestroy } from '@angular/core';

import { LogService } from '@ucap/ng-logger';
import { Subject, of } from 'rxjs';
import { Store, select } from '@ngrx/store';
import { takeUntil, take, map, catchError } from 'rxjs/operators';
import { RoomSelector, RoomActions } from '@ucap/ng-store-chat';
import { RoomInfo, ExitAllRequest } from '@ucap/protocol-room';
import { MatDialog } from '@angular/material/dialog';
import {
  ConfirmDialogComponent,
  ConfirmDialogData,
  ConfirmDialogResult
} from '@ucap/ng-ui';
import { I18nService } from '@ucap/ng-i18n';

@Component({
  selector: 'app-pages-chat-sidenav',
  templateUrl: './sidenav.page.component.html',
  styleUrls: ['./sidenav.page.component.scss']
})
export class SidenavPageComponent implements OnInit, OnDestroy {
  searchObj: any = {
    isShowSearch: false,
    searchWord: ''
  };

  checkable = false;

  roomList: RoomInfo[];
  selectedRoomList: RoomInfo[] = [];
  searchResultList: RoomInfo[] = [];

  private ngOnDestroySubject: Subject<boolean>;

  constructor(
    private store: Store<any>,
    private dialog: MatDialog,
    private i18nService: I18nService,
    private logService: LogService,
    private changeDetectorRef: ChangeDetectorRef
  ) {}

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

    // language setting
    this.i18nService.setDefaultNamespace('chat');

    this.store
      .pipe(takeUntil(this.ngOnDestroySubject), select(RoomSelector.rooms))
      .subscribe((rooms) => {
        rooms = (rooms || []).filter((info) => info.isJoinRoom);
        this.roomList = rooms;
      });
  }

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

  onToggleChackable(checkable: boolean): void {
    if (!!checkable) {
      if (!!this.selectedRoomList && this.selectedRoomList.length > 0) {
        const dialogRef = this.dialog.open<
          ConfirmDialogComponent,
          ConfirmDialogData,
          ConfirmDialogResult
        >(ConfirmDialogComponent, {
          data: {
            title: this.i18nService.t('dialog.title.exitFromRoom'),
            html: this.i18nService.t('dialog.confirmExitFromRoom')
          }
        });

        dialogRef
          .afterClosed()
          .pipe(take(1))
          .subscribe((result) => {
            if (!!result && !!result.choice) {
              this.store.dispatch(
                RoomActions.delMulti({
                  req: {
                    roomIds: this.selectedRoomList.map(
                      (roomInfo) => roomInfo.roomId
                    )
                  } as ExitAllRequest
                })
              );
            }
          });
      }
    } else {
      this.selectedRoomList = [];
    }

    this.checkable = checkable;
  }

  getCheckedAllItem(): boolean {
    const targetRoomList = !!this.searchObj.isShowSearch
      ? this.searchResultList
      : this.roomList;

    if (
      !targetRoomList ||
      targetRoomList.length === 0 ||
      targetRoomList.filter(
        (item) =>
          !(
            this.selectedRoomList.filter((info) => info.roomId === item.roomId)
              .length > 0
          )
      ).length > 0
    ) {
      return false;
    } else {
      return true;
    }
  }

  onToggleAllItem(value: boolean): void {
    if (!!value) {
      const targetRoomList = !!this.searchObj.isShowSearch
        ? this.searchResultList
        : this.roomList;

      this.selectedRoomList = targetRoomList.slice();
    } else {
      this.selectedRoomList = [];
    }
    this.changeDetectorRef.detectChanges();
  }

  onToggleItem(event: { checked: boolean; roomInfo: RoomInfo }): void {
    if (!!event.checked) {
      if (
        !this.selectedRoomList.some(
          (info) => info.roomId === event.roomInfo.roomId
        )
      ) {
        this.selectedRoomList.push(event.roomInfo);
      }
    } else {
      if (!!this.selectedRoomList && this.selectedRoomList.length > 0) {
        const index = this.selectedRoomList.findIndex(
          (info) => info.roomId === event.roomInfo.roomId
        );
        if (index > -1) {
          this.selectedRoomList.splice(index, 1);
        }
      }
    }
  }

  /** Searching */
  onKeyDownSearch(params: { searchWord: string }) {
    this.searchObj = {
      isShowSearch: true,
      searchWord: params.searchWord
    };
    this.changeDetectorRef.detectChanges();
  }
  /** Searching cancel */
  onClickCancel() {
    this.searchObj = {
      isShowSearch: false,
      searchWord: ''
    };
    this.changeDetectorRef.detectChanges();
  }

  onSearchResultList(searchResultList: RoomInfo[]) {
    this.searchResultList = searchResultList;
  }
}
