import { Component, OnInit, Optional, QueryList } from '@angular/core';
import { MdDialogRef } from '@angular/material';
import { DaterangepickerConfig } from 'ng2-daterangepicker';
import { NotificationService } from '../../services/notification.service';
import { User } from '../../model/user';
import { Notification } from '../../model/notification';
import { Status } from '../../model/status';
import { Branch } from '../../model/branch';
import { GridTerritory } from '../../model/gridterritory';
import { FilterMatrix } from '../../model/controller-model/filter-matrix';
import { TerritoryResponsibility } from '../../model/territory-responsibility';
import { AbstractListComponent } from '../../lists/abstract-list/abstract-list.component';
import { SessionContext } from '../../common/session-context';
import { BannerMessage } from '../../common/banner-message';
import { StatusEn, BannerMessageStatusEn, ErrorType } from '../../common/enums';
import { FormattedTimestampPipe } from '../../common-components/pipes/formatted-timestamp.pipe';
import { MessageService } from '../../services/message.service';
@Component({
  selector: 'app-entry',
  templateUrl: './entry.component.html',
  styleUrls: ['./entry.component.css']
})
export class EntryComponent implements OnInit {
  private originalNotification: Notification;

  isEditDialog = false;
  isReadOnlyDialog = false;
  isInstructionDialog = false;
  user: User = null;
  notification: Notification = new Notification();
  selectedStatusId: number;
  notificationVersion: Notification = new Notification();
  notificationVersions: Notification[];
  gridTerritories: GridTerritory[];
  branches: Branch[];
  statuses: Status[];
  defaultBranch = '';
  defaultGridTerritory = '';

  constructor(
    public dialogRef: MdDialogRef<EntryComponent>,
    private daterangepickerConfig: DaterangepickerConfig,
    private notificationService: NotificationService,
    public sessionContext: SessionContext,
    private messageService: MessageService) {
  }

  ngOnInit() {
    this.gridTerritories = this.sessionContext.getMasterGridTerritories();
    this.branches = this.sessionContext.getBranches();
    this.statuses = this.sessionContext.getStatuses();
    this.user = this.sessionContext.getCurrUser();

    this.daterangepickerConfig.settings = {
      singleDatePicker: true,
      timePicker: true,
      timePicker24Hour: true,
      timePickerSeconds: false,
      timePickerIncrement: 1,
      useCurrent: true,
      drops: 'up',
      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
      }
    };

    if (!this.notification.beginDate) {
      this.notification.beginDate = this.getCurrentDateTime();
    }

    if (!this.notification.createUser) {
      this.notification.createUser = this.user.name;
    }

    if (!this.notification.fkRefBranch) {
      this.defaultBranch = this.getUniqueBranchNameForUser(
        this.sessionContext.getfilterMatrix().responsibilityContainerMatrix,
        this.sessionContext.getCurrUser().username);
      const branchTmp = this.branches.filter((b) => b.name === this.defaultBranch)[0];
      if (branchTmp) {
        this.notification.fkRefBranch = branchTmp.id;
      }
    }

    if (!this.notification.fkRefGridTerritory) {
      this.defaultGridTerritory = this.getUniqueGridTerritoryNameForUser(
        this.sessionContext.getfilterMatrix().responsibilityContainerMatrix,
        this.sessionContext.getCurrUser().username);
      const gridTerritoryTmp = this.sessionContext.getGridTerritories().filter((gt) => gt.description === this.defaultGridTerritory)[0];
      if (gridTerritoryTmp) {
        this.notification.fkRefGridTerritory = gridTerritoryTmp.id;
      }
    }
  }

  onNotificationVersionChange(version: number) {
    this.notification = this.notificationVersions.find(notification => Number(notification.version) === Number(version));
  }

  setNotification(notification: Notification) {
    this.originalNotification = notification;
    this.notification = Object.assign(new Notification(), notification);
    this.notificationVersion = notification;
    if (!this.notification.beginDate) {
      this.notification.beginDate = this.getCurrentDateTime();
    }

    this.notificationService.getNotificationVersions(notification.incidentId).subscribe(notes => this.notificationVersions = notes,
      error => {
        this.messageService.emitError('Versionen', ErrorType.retrieve);
        this.dialogRef.close();
      }
    );
  }

  edit() {
    this.notification.responsibilityControlPoint = this.user.name;
    const notificationClone = Object.assign(new Notification(), this.notification);
    notificationClone.decoratorNotificationVersions = undefined;

    this.notificationService.updateNotification(notificationClone).subscribe(result => this.dialogRef.close(),
      error => {
        this.messageService.emitError('Eintrag', ErrorType.update);
        this.dialogRef.close();
      });
    this.daterangepickerConfig.settings.singleDatePicker = false;
  }

  add(adminFlag: boolean) {
    this.notification.responsibilityControlPoint = this.user.name;
    this.notification.adminFlag = adminFlag;
    this.notificationService.createNotification(this.notification).subscribe(result => this.dialogRef.close(),
      error => {
        this.messageService.emitError('Eintrags', ErrorType.create);
        this.dialogRef.close();
      });
    this.daterangepickerConfig.settings.singleDatePicker = false;
  }

  cancel() {
    this.dialogRef.close();
    this.daterangepickerConfig.settings.singleDatePicker = false;
  }

  statusChanged(statusId: number, notification: Notification) {
    const statusIdNum: number = Number(statusId);
    if (statusIdNum === StatusEn.done || statusIdNum === StatusEn.closed) {
      notification.finishedDate = this.getCurrentDateTime();
    } else {
      notification.finishedDate = null;
    }
  }

  getCurrentDateTime() {
    return new Date().toISOString();
  }

  getUniqueBranchNameForUser(responsibilityContainerMatrix: TerritoryResponsibility[], currentUserName: string): string {
    let uniqueBranchName = '';
    let branchNames: string[] = [];

    responsibilityContainerMatrix.forEach((gridTerritory) => {
      gridTerritory.responsibilityList.forEach((responsibility) => {
        if (responsibility.responsibleUser === currentUserName) {
          branchNames.push(responsibility.branchName);
        }
      });
    });

    branchNames = branchNames.filter((item, pos, ar) => ar.indexOf(item) === pos);

    if (branchNames.length === 1) {
      uniqueBranchName = branchNames[0];
    } else {
      uniqueBranchName = '';
    }

    return uniqueBranchName;
  }


  getUniqueGridTerritoryNameForUser(responsibilityContainerMatrix: TerritoryResponsibility[], currentUserName: string): string {
    let uniqueGridTerritoryName = '';
    let gridTerritoryNames: string[] = [];
    const gridTerritories = this.sessionContext.getGridTerritories();

    responsibilityContainerMatrix.forEach((gridTerritory) => {
      gridTerritory.responsibilityList.forEach((responsibility) => {
        if (responsibility.responsibleUser === currentUserName) {
          const gtTmp = gridTerritories.filter(
            (gt) => gt.description === gridTerritory.gridTerritoryDescription)[0];
          if (gtTmp) {
            const masterGridTerritoryID = gtTmp.fkRefMaster;
            const masterGridTerritory = gridTerritories.filter((mGT) => mGT.id === masterGridTerritoryID)[0];
            gridTerritoryNames.push(masterGridTerritory.description);
          }
        }
      });
    });

    gridTerritoryNames = gridTerritoryNames.filter((item, pos, ar) => ar.indexOf(item) === pos);

    if (gridTerritoryNames.length === 1) {
      uniqueGridTerritoryName = gridTerritoryNames[0];
    } else {
      uniqueGridTerritoryName = '';
    }
    return uniqueGridTerritoryName;
  }
}
