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();
      });
  }

  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();
      });
  }

  cancel() {
    this.dialogRef.close();
  }

  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;
  }
}
