/**
******************************************************************************
* Copyright © 2017-2018 PTA GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* 
*     http://www.eclipse.org/legal/epl-v10.html
* 
******************************************************************************
*/
import { Component, OnDestroy, OnInit, Input, Output, EventEmitter, AfterViewChecked, SimpleChanges, OnChanges } from '@angular/core';
import { NotificationService } from '../../services/notification.service';
import { ReminderService } from '../../services/reminder.service';
import { Notification } from '../../model/notification';
import { SortingState } from '../../model/sorting-state';
import { SessionContext } from '../../common/session-context';
import { DaterangepickerConfig } from 'ng2-daterangepicker';
import { Router } from '@angular/router';
import { StatusEn, BannerMessageStatusEn, ErrorType } from '../../common/enums';
import { Globals } from '../../common/globals';
import { TerritoryResponsibility } from '../../model/territory-responsibility';
import { NotificationSearchFilter } from '../../model/notification-search-filter';
import { ResponsibilitySearchFilter } from '../../model/responsibility-search-filter';
import { NotificationHistoryExpansionState } from '../../model/notificationhistoryexpansionstate';
import { ResponsibilityService } from '../../services/responsibility.service';
import { User } from '../../model/user';
import { MessageService, MessageDefines } from '../../services/message.service';
import { BannerMessage } from '../../common/banner-message';
import { ListHelperTool } from '../../common/list-helper-tool';
import { UserSettings } from 'app/model/user-settings';
import { UserService } from 'app/services/user.service';

@Component({
  selector: 'app-abstract-list',
  templateUrl: './abstract-list.component.html',
  styleUrls: ['./abstract-list.component.css']
})

export class AbstractListComponent implements OnInit, OnChanges, OnDestroy {
  @Output() onEditNotification = new EventEmitter<Notification>();
  @Output() onLookUpNotification = new EventEmitter<Notification>();
  @Input() shiftChangeTransactionId: number;
  @Input() withCheckboxes = false;
  @Input() withDatePicker = true;
  @Input() withEditButtons = true;
  @Input() isCollapsible = true;
  @Input() stayHidden = true;
  @Input() gridId: string;
  @Input() enforceShowReadOnly = false;
  showSpinner = false;
  globals = Globals;
  router: Router;
  selectAll = false;
  defaultList: Notification[];
  notifications: Notification[];
  currentDate = new Date();
  responsibilitySearchFilter = new ResponsibilitySearchFilter();
  notificationSearchFilter = new NotificationSearchFilter();
  endDate: Date;
  startDate: Date;
  minDate: Date;
  maxDate: Date;
  user: User = null;
  collapseStateId: string;

  sortingState: SortingState = new SortingState();
  subscription: any;

  private subscriptions: Array<any>;
  constructor(
    protected messageService: MessageService,
    protected notificationService: NotificationService,
    protected reminderService: ReminderService,
    protected sessionContext: SessionContext,
    protected daterangepickerConfig: DaterangepickerConfig,
    protected userService: UserService) { }

  ngOnChanges(changes: SimpleChanges) {
    if (changes['shiftChangeTransactionId'] !== undefined && changes['shiftChangeTransactionId'].currentValue !== undefined) {
      this.onShiftChangeTransactionChanged();
    }
  }

  ngOnDestroy() {
    this.subscriptions.forEach(item => item.unsubscribe());
  }

  ngOnInit() {
    this.init();
    
  }
  protected init() {
    this.setDefaultDateRange();
    this.user = this.sessionContext.getCurrUser();
    this.collapseStateId = this.gridId + this.globals.COLLAPSE_STATE_ID_EXT;

    const oldStayHiddenVal = this.sessionContext.getCollapseState(this.collapseStateId);
    if (oldStayHiddenVal != null) {
      this.stayHidden = oldStayHiddenVal;
    }

    //Subscriptions
    let subscription: any;
    this.subscriptions = new Array<any>();
    subscription = this.messageService.matrixFilterChanged$.subscribe(filterList => {
      this.onFilterSelectionChanged(filterList);
    });
    this.subscriptions.push(subscription);

    subscription = this.notificationService.itemAdded$.subscribe(item => this.onItemAdded(item));
    this.subscriptions.push(subscription);

    subscription = this.notificationService.itemChanged$.subscribe(item => this.onItemChanged(item));
    this.subscriptions.push(subscription);

    subscription = this.reminderService.itemAdded$.subscribe(item => this.onItemAdded(item));
    this.subscriptions.push(subscription);

    subscription = this.reminderService.itemChanged$.subscribe(item => this.onItemChanged(item));
    this.subscriptions.push(subscription);

    //Daterangepicker Config
    this.daterangepickerConfig.settings = {
      timePicker: true,
      timePicker24Hour: true,
      timePickerSeconds: false,
      timePickerIncrement: 1,
      useCurrent: true,
      locale: {
        format: 'DD.MM.YYYY HH:mm',
        applyLabel: '&Uuml;bernehmen',
        cancelLabel: 'Abbrechen',
        daysOfWeek: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],
        monthNames: ['Januar', 'Februar', 'M&auml;rz', 'April', 'Mai', 'Juni', 'Juli',
          'August', 'September', 'Oktober', 'November', 'Dezember'],
        firstDay: 1
      }
    };

  }

  protected setDefaultDateRange(): void {

  }

  protected onShiftChangeTransactionChanged() {
    this.notificationSearchFilter = new NotificationSearchFilter();
    this.notificationSearchFilter.historicalFlag = true;
    this.notificationSearchFilter.shiftChangeTransactionId = this.shiftChangeTransactionId;
    this.getHistoricalNotifications();
  }

  protected onFilterSelectionChanged(responsibilityFilterList: number[]) {
    this.notificationSearchFilter = new NotificationSearchFilter();
    this.notificationSearchFilter.responsibilityFilterList = responsibilityFilterList;
    this.getNotifications();
  }

  protected onItemChanged(changedNotification: Notification): void {

  }


  onItemAdded(newNotification: Notification): void {

  }

  protected setNotifications(newNotifications: Notification[]) {
    this.notifications = newNotifications;
    this.defaultList = Object.assign(new Array<Notification>(), newNotifications);
    newNotifications.forEach(notification => {
      notification.historyOpen = this.sessionContext.getNotificationHistoryExpansionStateById(notification.incidentId);
      if (notification.historyOpen) {
        this.retrieveNotificationVersions(notification);
      }
    });

    this.processSortingState();
    
  }

  protected processSortingState(){
    
    const userSettings: UserSettings = this.sessionContext.getUsersSettings();    
    let sortingState;
    if (userSettings.sortingStateMap){
      sortingState = userSettings.sortingStateMap.get(this.gridId);
    }      
    
    //Default for open notifications
    if (this.gridId === Globals.SORTING_STATE_GRID_ID_OPEN_NOTS && !sortingState) {
      sortingState = new SortingState();
      sortingState.column = 'beginDate';
      sortingState.isDesc = false;
      sortingState.counter = 2;
    }
    
    //Default for others notifications
    if (!sortingState) {
      sortingState = new SortingState();
      sortingState.defaultState = true;
    }
    
    this.sortingState = sortingState;
    this.sort(undefined);
  }

  protected setNotificationVersions(newNotificationsVersions: Notification[], notification: Notification) {
    notification.decoratorNotificationVersions =
      newNotificationsVersions.filter(notificationsVersion => notificationsVersion.id !== notification.id);
  }



  getNotifications(): void {

  }
  getHistoricalNotifications(): void {

  }

  retrieveNotificationVersions(notification: Notification): void {
    this.notificationService.getNotificationVersions(notification.incidentId).subscribe(
      nots => this.setNotificationVersions(nots, notification),
      error => {
        console.log(error);
        this.messageService.emitError('Meldungsversionen', ErrorType.retrieve);
      }
    );
  }

  getNotificationVersions(notification: Notification): Notification[] {
    return notification.decoratorNotificationVersions;
  }

  editNotification(notification: Notification) {
    this.onEditNotification.emit(notification);
  }

  toggleCollapse(type: string) {
    let currentState = this.sessionContext.getCollapseState(this.collapseStateId);
    if (!currentState) {
      currentState = this.stayHidden;
    }
    this.sessionContext.setCollapseState(!currentState, this.collapseStateId);
  }

  toggleHistoryTab(notification: Notification) {
    notification.historyOpen = !notification.historyOpen;

    this.sessionContext.setNotificationHistoryExpansionStateById(notification.incidentId, notification.historyOpen);
    if (notification.historyOpen) {
      this.retrieveNotificationVersions(notification);
    }
  }

  lookUpNotification(notification: Notification) {
    this.onLookUpNotification.emit(notification);
  }

  changeAllSelection(): void {
    if (this.selectAll) {
      for (const info of this.notifications) {
        info.selected = true;
      }
    } else {
      for (const info of this.notifications) {
        info.selected = false;
      }
    }
  }

  selectionChanged(): void {
    if (this.notifications) {
      let allSelected = true;
      for (const info of this.notifications) {
        if (!info.selected) {
          allSelected = false;
          break;
        }
      }
      this.selectAll = allSelected;
    }
  }

  isSpecialUser(): boolean {
    return this.user && this.user.specialUser;
  }

  isEnforceShowReadOnly(): boolean {
    return this.enforceShowReadOnly;
  }

  public sort(column: string) {

    if (column) {

      this.sortingState.isDesc = !this.sortingState.isDesc;
      if (this.sortingState.column !== undefined && this.sortingState.column !== column) {
        this.sortingState.counter = 1;
        this.sortingState.isDesc = true;
      } else {
        this.sortingState.counter++;
      }
      this.sortingState.column = column;
    }


    if (this.sortingState.defaultState && !column || this.sortingState.counter > 0 && this.sortingState.counter % 3 === 0) {
      this.sortingState.counter = 0;
      this.notifications = Object.assign(new Array<Notification>(), this.defaultList);
      this.sortingState.defaultState = true;
      this.sortingState.isDesc = false;
    } else {
      this.sortingState.defaultState = false; 
      this.sortNotifications();
    }

    if (!column || !this.gridId) return;

    this.updateUserSettingsSorting();    

  };

  updateUserSettingsSorting(){    
    const userSettings: UserSettings = this.sessionContext.getUsersSettings();        

    if(!userSettings.sortingStateMap) {
      userSettings.sortingStateMap = new Map();
    }
    userSettings.sortingStateMap.set(this.gridId, this.sortingState);
    this.sessionContext.setUsersSettings(userSettings);

    this.userService.postUserSettings(userSettings).subscribe(resp => {},
    error => {
      console.log(error);
    });

  }

  private sortNotifications() {
    if(!this.notifications) return;
    const direction = this.sortingState.isDesc ? 1 : -1;
    this.notifications.sort((a, b) => {

      const a1 = this.getColumnValue(this.sortingState.column, a);
      const b1 = this.getColumnValue(this.sortingState.column, b);

      if (a1 == null) {
        return 1 * direction;
      }
      if (b1 == null) {
        return -1 * direction;
      } else if (a1 < b1) {
        return -1 * direction;
      } else if (a1 > b1) {
        return 1 * direction;
      } else {
        return 0;
      }
    });
  }

  private getColumnValue(columnName: string, notification: Notification) {

    switch (columnName) {
      case 'fkRefBranch':
        return this.sessionContext.getBrancheById(notification.fkRefBranch) ?
          this.sessionContext.getBrancheById(notification.fkRefBranch).name.toLowerCase() : null;
      case 'fkRefNotificationStatus':
        return this.sessionContext.getStatusById(notification.fkRefNotificationStatus) ?
          this.sessionContext.getStatusById(notification.fkRefNotificationStatus).name.toLowerCase() : null;
      case 'fkRefGridTerritory':
        return this.sessionContext.getGridTerritoryById(notification.fkRefGridTerritory) ?
          this.sessionContext.getGridTerritoryById(notification.fkRefGridTerritory).name.toLowerCase() : null;
      default:
        return notification[columnName] ? notification[columnName].toLowerCase() : null;
    }

  }

  public getListHelperTool() {
    return new ListHelperTool();
  }


}

