/*
 * Copyright (C) 2019 Robert Bosch GmbH Copyright (C) 2019 Robert Bosch Manufacturing Solutions GmbH, Germany. All rights reserved.
 */
import { animate, state, style, transition, trigger } from '@angular/animations';
import { SelectionModel } from '@angular/cdk/collections';
import { Component, OnInit } from '@angular/core';
import { MatDialogRef } from '@angular/material/dialog';
import { MatTableDataSource } from '@angular/material/table';
import { BehaviorSubject, combineLatest } from 'rxjs';
import { debounceTime, map } from 'rxjs/operators';
import {
  ITEM_EXPANDED_STATES,
  SIDENAV_LINKS_ANIMATION_TIMING,
} from '../layout/bci-sidebar-nav-item/bci-sidebar-nav-item.component';
import { BciSidebarService } from '../layout/bci-sidebar/bci-sidebar.service';
import { ModalWindowService } from '../modal-window/modal-window.service';
import { NotificationItem } from '../notification/notification.models';
import { NotificationService } from '../notification/notification.service';
import { BciMessagesFilterComponent } from './bci-messages-filter/bci-messages-filter.component';
import { BciMessagesFilterService } from './bci-messages.filter.service';
import { BciMessagesIntl } from './messages-intl';

@Component({
  selector: 'bci-messages',
  templateUrl: './bci-messages.component.html',
  styleUrls: ['./bci-messages.component.scss'],
  animations: [
    trigger('indicatorRotate', [
      state(ITEM_EXPANDED_STATES.collapsed, style({ transform: 'rotate(90deg)' })),
      state(ITEM_EXPANDED_STATES.expanded, style({ transform: 'rotate(-90deg)' })),
      transition(
        `${ITEM_EXPANDED_STATES.expanded} <=> ${ITEM_EXPANDED_STATES.collapsed}`,
        animate(SIDENAV_LINKS_ANIMATION_TIMING)
      ),
    ]),
  ],
})
export class BciMessagesComponent implements OnInit {
  displayedColumns = ['expand', 'date', 'type', 'message', 'goto'];
  dataSource = new BehaviorSubject<MatTableDataSource<NotificationItem>>(new MatTableDataSource());
  selection: SelectionModel<NotificationItem> = new SelectionModel<NotificationItem>(true, []);

  filters = new BehaviorSubject([]);
  searchTerm = new BehaviorSubject<string>('');
  expanded = true;

  constructor(
    public messagesIntl: BciMessagesIntl,
    private modalWindowService: ModalWindowService,
    private dialogRef: MatDialogRef<BciMessagesComponent>,
    private notificationService: NotificationService,
    private sidebarService: BciSidebarService,
    private filterService: BciMessagesFilterService
  ) {}

  ngOnInit() {
    combineLatest([this.notificationService.getSessionNotifications(), this.searchTerm, this.filters])
      .pipe(
        map(([data, searchTerm, filters]) => this.applyTextFilter(data, searchTerm, filters)),
        map(([data, searchTerm, filters]) => this.applyFilter(data, searchTerm, filters)),
        map(([data]) => new MatTableDataSource<NotificationItem>(data)),
        debounceTime(0)
      )
      .subscribe((table) => this.dataSource.next(table));
  }

  public filter(): void {
    const filterDialog = this.modalWindowService.openDialogWithComponent(BciMessagesFilterComponent, {
      width: '90%',
    });
    filterDialog.afterClosed().subscribe((dataChanged) => {
      if (dataChanged) {
        this.filters.next(this.filterService.filter);
      }
    });
  }

  public search(searchTerm: string): void {
    this.searchTerm.next(searchTerm.trim().toLowerCase());
  }

  public deleteMessages(): void {
    this.notificationService.deleteSessionNotifications(this.selection.selected);
    this.selection.clear();
  }

  public deactivateFilter(type: string): void {
    this.filterService.deactivateFilter(type);
    this.filters.next(this.filterService.filter);
  }

  public typeSelect(types: Array<string>) {
    this.filterService.filter = types;
    this.filters.next(this.filterService.filter);
  }

  public getExpandedState(element: NotificationItem) {
    return this.selection.selected.indexOf(element) > -1 ? 'expanded' : 'collapsed';
  }

  public goTo(url: string) {
    this.sidebarService.navigateToUrl(url);
    this.dialogRef.close();
  }

  private applyFilter(data: Array<NotificationItem>, searchTerm: string, filters: any): any {
    if (filters.length > 0) {
      return [data.filter((notification) => filters.indexOf(notification.type) !== -1), searchTerm, filters];
    }
    return [data, searchTerm, filters];
  }

  private applyTextFilter(data: Array<NotificationItem>, searchTerm: string, filters: any): any {
    if (!searchTerm) {
      return [data, searchTerm, filters];
    }

    return [
      data.filter((notification) => JSON.stringify(notification).toLowerCase().indexOf(searchTerm) > -1),
      searchTerm,
      filters,
    ];
  }
}
