/*
******************************************************************************
* Copyright © 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, OnInit, Input, ElementRef, ViewChild, AfterContentChecked,
  SimpleChanges, OnChanges, Output, AfterViewChecked
} from '@angular/core';
import { FormGroup } from '@angular/forms';
import { SessionContext } from '../../common/session-context';
import { GridMeasure } from '../../model/grid-measure';
import { Globals } from '../../common/globals';
import { ErrorType } from '../../common/enums';
import { DocumentService } from '../../services/document.service';
import { Document } from './../../model/document';
import { saveAs } from 'file-saver/FileSaver';
import { RoleAccessHelperService } from '../../services/jobs/role-access-helper.service';
import { EventEmitter, AfterViewInit } from '@angular/core';
import { Util } from '../../common/util';
import { GridMeasureService } from '../../services/grid-measure.service';
import { ToasterMessageService } from '../../services/toaster-message.service';

@Component({
  selector: 'app-grid-measure-detail-tab',
  templateUrl: './grid-measure-detail-tab.component.html',
  styleUrls: ['./grid-measure-detail-tab.component.css', '../grid-measure-detail/grid-measure-detail.component.css']
})
export class GridMeasureDetailTabComponent implements OnInit, OnChanges, AfterViewChecked, AfterViewInit {

  @Input() showSpinnerGrid: boolean;
  @Input() id: any;
  @Input() gridMeasureDetail: GridMeasure = new GridMeasure();
  @Input() readOnlyForm: boolean;
  @Output() isValidForSave: EventEmitter<boolean> = new EventEmitter<boolean>();

  Globals = Globals;
  fileToUpload: File = null;
  fileName: string;
  fileSelected: boolean;
  documentToUpload: Document = null;
  listOfDocuments: Document[] = null;
  listOfDocumentsNames: string[] = [];
  dataURI: string;
  showSpinnerFileUpload = false;
  dragEntered = false;
  isAppointmentNumberOfValid: boolean;
  switchingObjectList: string[];
  appointmentRepetitionList: string[];
  showSpinnerGridFileUpload: boolean;
  dateFormatLocale = 'dd.MM.yyyy HH:mm';
  affectedResourcesList: Array<string> = [];
  inactiveFields: Array<string> = [];
  departmentList: any;

  datePattern = '^(([0-2]?[0-9]|3[0-1])\.([0]?[1-9]|1[0-2])\.[1-2][0-9]{3})$';
  dateTimePattern = '^(([0-2]?[0-9]|3[0-1])\.([0]?[1-9]|1[0-2])\.[1-2][0-9]{3}) (20|21|22|23|[0-1]?[0-9]{1}):([0-5]?[0-9]{1})$';
  calcDatepickerDropOrientation = Util.calcDatepickerDropOrientation;

  @ViewChild('gridMeasureDetailForm') gridMeasureDetailForm: FormGroup;
  @ViewChild('gridMeasureDetailTabContainer') gridMeasureDetailTabContainer: ElementRef;


  constructor(public sessionContext: SessionContext,
    private documentService: DocumentService,
    public roleAccessHelper: RoleAccessHelperService,
    protected gridMeasureService: GridMeasureService,
    private toasterMessageService: ToasterMessageService,
    private gridMeasuresService: GridMeasureService) { }

  ngOnInit() {

    this.inactiveFields = this.sessionContext.getInactiveFields();
    this.isAppointmentNumberOfValid = true;

    this.getAffectedResourcesDistinct();

    // TODO auslagern in Globals bzw. je nach Prozess automatisch laden (separate User Story)
    this.switchingObjectList = ['UW A', 'UW B', 'test1', 'test2'];
    this.appointmentRepetitionList = this.sessionContext.getBackendsettings().appointmentRepetition.map(ap => ap.name);
    this.gridMeasuresService.getUserDepartments()
      .subscribe(departments => this.departmentList = departments,
        error => {
          console.log(error);
        });
  }

  ngAfterViewInit() {
    this.initInactiveFields();
  }

  ngAfterViewChecked() {
    if (this.gridMeasureDetailForm) {
      this.gridMeasureDetail._isValide = this.gridMeasureDetailForm.valid;
    }
  }

  ngOnChanges(changes: SimpleChanges) {
    if (changes['id'] && changes['id'].currentValue) {
      this.getDocumentsForId();
    }
    if (changes['readOnlyForm']) {
      this.initInactiveFields();
    }
    if (changes['gridMeasureDetail'] && changes['gridMeasureDetail'].currentValue) {
      this.gridMeasureDetail.appointmentNumberOf = this.gridMeasureDetail.appointmentNumberOf || 0;
      this.appointmentRepetitionList = this.sessionContext.getBackendsettings().appointmentRepetition.map(ap => ap.name);
      if (!this.gridMeasureDetail.appointmentRepetition) {
        this.gridMeasureDetail.appointmentRepetition = this.appointmentRepetitionList[0];
      }
      this.setCurrTimeIfEmpty(this.gridMeasureDetail);
    }
  }

  getAffectedResourcesDistinct() {
    this.gridMeasureService.getAffectedResourcesDistinct().subscribe(aResource =>
      this.affectedResourcesList = aResource);
  }

  public initInactiveFields() {
    const el: HTMLElement = this.gridMeasureDetailTabContainer.nativeElement as HTMLElement;
    const fields = el.querySelectorAll('*[id]:not(button)');
    for (let index = 0; index < fields.length; index++) {
      const field = fields[index];
      if (this.readOnlyForm || this.isFieldInactive(field['id'])) {
        field.setAttribute('disabled', 'disabled');
      } else {
        field.removeAttribute('disabled');
      }
    }
  }

  private isFieldInactive(fieldName: string): boolean {
    if ((fieldName === 'fileUploadLabel' || fieldName === 'file') && !this.id) {
      return true;
    } else {
      return this.inactiveFields.filter(field => field === fieldName).length > 0;
    }
  }
  setCurrTimeIfEmpty(gridMeasure: GridMeasure) {

    const dateFields = [
      'appointmentStartdate',
      'plannedStarttimeFirstSinglemeasure'
    ];
    if (gridMeasure.id) {
      return;
    }
    dateFields.forEach(field => {
      if (gridMeasure[field] === undefined) {
        gridMeasure[field] = this.getCurrentDateTime();
      }
    });

  }

  public selectedDate(value: any, datepicker?: any) {
    this.gridMeasureDetail[datepicker] = value.start._d;
  }
  onGridMeasureDetailFormValidation(valid: boolean) {
    this.gridMeasureDetail._isValide = valid;
  }
  getCurrentDateTime(): string {
    return new Date().toISOString();
  }
  checkAppointmentNumberOfValue(event) {
    if (event < Globals.APPOINTMENT_NUMBER_OF_MAX_VALUE + 1) {
      this.isAppointmentNumberOfValid = true;
    } else {
      this.gridMeasureDetail.appointmentNumberOf = 0;
      this.isAppointmentNumberOfValid = false;
    }
  }
  onGridMeasureTitleChange(value) {
    if (value) {
      this.isValidForSave.emit(true);
    } else {
      this.isValidForSave.emit(false);
    }
  }

  handleFileInput(file: FileList) {
    if (!file || file.length === 0) {
      return;
    }

    if (file.length > 1) {
      this.toasterMessageService.showWarn('Es kann nur jeweils eine Datei hochgeladen werden! '
        + 'Die erste Datei ihrer Auswahl wurde übernommen.');

    }

    this.fileToUpload = file.item(0);
    this.fileName = this.fileToUpload.name;

    if (this.gridMeasureDetail.statusId === Globals.STATUS.APPLIED && this.checkIfFileExists(this.fileToUpload.name)) {
      this.toasterMessageService.showWarn('Im Status Beantragt können Dateien nicht geändert werden!');
      return;
    }

    if (!this.fileSizeCheck() || !this.fileTypeCheck()) {
      return;
    }
    this.fileSelected = true;
  }


  private checkIfFileExists(fileName: string) {
    if (this.listOfDocumentsNames.includes(fileName)) {
      return true;
    } else {
      return false;
    }
  }

  private fileTypeCheck(): boolean {
    const fileType = this.fileToUpload.type;
    if (!Globals.TYPE_WHITELIST.includes(fileType)) {
      this.toasterMessageService.showWarn('Dieser Dateityp ist nicht erlaubt!');
      return false;
    } else {
      return true;
    }
  }

  private fileSizeCheck(): boolean {
    const fileUploadSize = this.fileToUpload.size;
    const allowed = Globals.MEGABYT_UNIT * Globals.MAX_UPLOADFILE_SIZE;
    if (fileUploadSize > allowed) {
      //   Globals.MAX_UPLOADFILE_SIZE + ' Megabytes!', MessageScopeEn.local);
      this.toasterMessageService.showWarn('Die ausgewählte Datei überschreitet die maximale zulässige Größe von ' +
        Globals.MAX_UPLOADFILE_SIZE + ' Megabytes!');
      return false;
    } else {
      return true;
    }
  }

  uploadDocument() {
    if (!this.fileSelected) {
      return;
    }
    this.showSpinnerFileUpload = true;
    // convertFileToBas64
    const reader = new FileReader();
    reader.onload = (e) => {
      this.dataURI = reader.result;
      this.proccessFile();
    };
    reader.readAsDataURL(this.fileToUpload);
  }

  private proccessFile() {
    const byteString = this.dataURI.split(',')[1];
    const documentToUpload = new Document();
    documentToUpload.data = byteString;

    // TODO send to backend to check file type against whitelist
    // const mimeString = this.dataURI.split(',')[0].split(':')[1].split(';')[0];
    documentToUpload.documentName = this.fileToUpload.name;

    this.documentToUpload = documentToUpload;
    this.processUpload();
  }

  private processUpload() {
    this.documentService.uploadGridMeasureAttachments(this.id, this.documentToUpload).subscribe(resp => {
      this.showSpinnerFileUpload = false;
      this.getDocumentsForId();
      this.fileSelected = false;
      this.toasterMessageService.showSuccess('Datei erfolgreich hochgeladen!');
    },
      error => {
        this.toasterMessageService.showError(ErrorType.upload, '');
        this.showSpinnerFileUpload = false;
        console.log(error);
      });
  }

  private getDocumentsForId() {
    this.documentService.getGridMeasureAttachments(this.id).subscribe(gm => {
      this.listOfDocuments = gm;
      for (let index = 0; index < this.listOfDocuments.length; index++) {
        this.listOfDocumentsNames.push(this.listOfDocuments[index].documentName);
      }
    },
      error => {
        this.toasterMessageService.showError(ErrorType.retrieve, 'GridMeasure');
        console.log(error);
      });
  }

  downloadDocument(documentId) {
    this.showSpinnerFileUpload = true;
    this.documentService.downloadGridMeasureAttachment(documentId).subscribe(resp => {
      this.saveFile(resp);
      this.toasterMessageService.showSuccess('Datei erfolgreich heruntergeladen!');
      this.showSpinnerFileUpload = false;
    },
      error => {
        this.toasterMessageService.showError(ErrorType.retrieve, 'Datei');
        this.showSpinnerFileUpload = false;
        console.log(error);
      });
  }

  deleteDocument(documentId: number, index: number) {
    this.documentService.deleteGridMeasureAttachment(documentId).subscribe(resp => {
      this.toasterMessageService.showSuccess('Datei erfolgreich gelöscht!');
      this.listOfDocuments.splice(index, 1);
    },
      error => {
        this.toasterMessageService.showError(ErrorType.delete, 'Datei');
        this.showSpinnerFileUpload = false;
        console.log(error);
      });
  }

  private saveFile(document: Document) {
    const byteString = atob(document.data);

    // write the bytes of the string to an ArrayBuffer
    const ab = new ArrayBuffer(byteString.length);

    // create a view into the buffer
    const ia = new Uint8Array(ab);

    // set the bytes of the buffer to the correct values
    for (let i = 0; i < byteString.length; i++) {
      ia[i] = byteString.charCodeAt(i);
    }

    // write the ArrayBuffer to a blob, and you're done
    const blob = new Blob([ab], { type: 'application/octet-stream' });
    saveAs(blob, document.documentName);

  }
  allowDrop(ev) {
    ev.preventDefault();
    ev.stopPropagation();
  }

  drop(ev) {
    ev.preventDefault();
    ev.stopPropagation();

    // cancel drop if upload is disabled
    const el: HTMLElement = this.gridMeasureDetailTabContainer.nativeElement as HTMLElement;
    const uploadField = el.querySelector('#fileUploadLabel');

    if (uploadField.getAttribute('disabled')) {
      this.dragEntered = false;
      return;
    }

    if (!this.readOnlyForm && this.id) {
      const files = ev.target.files || ev.dataTransfer.files;
      this.handleFileInput(files);
    }
    this.dragEntered = false;
  }

  dragenter(ev) {
    this.dragEntered = true;
  }

  dragleave(ev) {
    this.dragEntered = false;
  }
}
