import { Component, OnInit, Inject } from '@angular/core';
import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms';
import { HttpEventType, HttpErrorResponse } from '@angular/common/http';
import { of } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { AgentService } from '../../../service/agent.service';
import { MatDialogRef, MatTableDataSource, MAT_DIALOG_DATA } from '@angular/material';
import { NotificationService, NotificationType } from '@xdf/commons';
import { TranslateService } from '@ngx-translate/core';

export class FileUploadModel {
  id: number;
  uuid: string;
  filename: string;
  status: string;
  user: string;
  uploadDate: string;
  description: string;

}
@Component({
  selector: 'byte-ca-file-upload-modal',
  templateUrl: './ca-file-upload-modal.component.html',
  styleUrls: ['./ca-file-upload-modal.component.scss']
})
export class CaFileUploadModalComponent implements OnInit {

  formGroup: FormGroup;

  accept = '.xls,.xlsx';

  enabledOK = false;

  createMode = true;

  fileInfo = new FileUploadModel();

  fileErrorDetail: any;

  dataSource = new MatTableDataSource([]);
  displayedColumns: string[] = [];
  applicationSettings: any;


  constructor(
    private formBuilder: FormBuilder,
    private agentService: AgentService,
    private notificationService: NotificationService,
    private translateService: TranslateService,
    public dialogRef: MatDialogRef<CaFileUploadModalComponent>,
    @Inject(MAT_DIALOG_DATA) public data: any
  ) {
    this.formGroup = this.formBuilder.group({
      description: new FormControl({ value: '', disabled: false }),
      file: new FormControl({ value: '', disabled: false }),
      filename: new FormControl({ value: '', disabled: true })
    });

    if (data) {
      this.fileInfo = data;
      this.formGroup.controls.description.setValue(this.fileInfo.description);
      this.formGroup.controls.filename.setValue(this.fileInfo.filename);

      this.createMode = false;
      this.enabledOK = true;
    }
  }

  ngOnInit() {
  }

  buildErrorDetail(status, detail) {
    this.fileErrorDetail = undefined;

    if ('CONTENT_ERROR' === status) {
      this.displayedColumns = ['line', 'type', 'value'];

      if (detail) {
        const fileErrorDetailTemp = [];

        for (const line of Object.keys(detail)) {
          const object = detail[line];

          const type = Object.keys(object)[0];

          fileErrorDetailTemp.push({
            line,
            type,
            value: object[type],
          });
        }

        if (fileErrorDetailTemp) {
          this.fileErrorDetail = fileErrorDetailTemp;
          this.dataSource.data = fileErrorDetailTemp;
        }

      }

    } else if ('HEADER_ERROR' === status) {
      this.displayedColumns = ['header', 'value'];

      if (detail) {
        const fileErrorDetailTemp = [];

        for (const header of Object.keys(detail)) {
          const value = detail[header];

          fileErrorDetailTemp.push({
            header,
            value,
          });
        }

        if (fileErrorDetailTemp) {
          this.fileErrorDetail = fileErrorDetailTemp;
          this.dataSource.data = fileErrorDetailTemp;
        }
      }
    } else {
      this.fileErrorDetail = undefined;
    }
  }

  retry() {
    this.fileErrorDetail = undefined;
  }

  uploadFile(event) {
    for (const i in event) {
      if (event[i] instanceof File) {
        const reader = new FileReader();
        reader.onload = () => {
          // this.formGroup.controls['imageAvatar'].setValue(reader.result as string);
        };
        reader.readAsDataURL(event[i]);

        const fileSelected = {
          data: event[i],
          state: 'in',
          inProgress: false,
          progress: 0,
          canRetry: false
        };

        this.validateFile(fileSelected);
      }
    }
  }

  validateFile(file) {

    const formData = new FormData();
    formData.append('file', file.data);

    file.inProgress = true;
    this.enabledOK = false;

    this.agentService.upload(formData).pipe(
      map(event => {
        switch (event.type) {
          case HttpEventType.UploadProgress:
            file.progress = Math.round(event.loaded * 100 / event.total);
            break;
          case HttpEventType.Response:
            return event;
        }
      }),
      catchError((error: HttpErrorResponse) => {
        file.inProgress = false;
        return of(`${file.data.name} upload failed.`);
      })
    ).subscribe((event: any) => {
      if (typeof (event) === 'object') {
        this.fileErrorDetail = undefined;
        this.enabledOK = false;
        const info = event.body;
        this.fileInfo = new FileUploadModel();
        if (info) {
          const status = info.fileValidationResult.status;

          if ('OK' === status) {
            this.fileInfo.id = info.id;
            this.fileInfo.description = this.formGroup.controls.description.value;
            this.fileInfo.uuid = info.uuid;
            this.fileInfo.filename = info.fileName;
            this.fileInfo.status = info.status;
            this.fileInfo.user = info.user;
            this.fileInfo.uploadDate = info.uploadDate;

            this.enabledOK = true;
            this.fileErrorDetail = undefined;

          } else if ('INCOMPATIBLE_EXTENSION' === status) {
            this.formGroup.controls.file.setValue(null);
            const message = 'label.file.incompatible.extension';
            this.enabledOK = false;
            this.fileErrorDetail = undefined;
            this.notificationService.showMessage(this.translateService.instant(message)
            + '[' + this.accept + ']', null, NotificationType.error);

          } else if ('CONTENT_ERROR' === status) {
            this.formGroup.controls.file.setValue(null);
            this.enabledOK = false;

            this.buildErrorDetail(status, info.fileValidationResult.recordsErrorMap);

          } else if ('HEADER_ERROR' === status) {
            this.formGroup.controls.file.setValue(null);
            this.enabledOK = false;

            this.buildErrorDetail(status, info.fileValidationResult.headersErrorMap);

          }

        } else {
          this.enabledOK = false;
          this.fileErrorDetail = undefined;
          this.formGroup.controls.file.setValue(null);
        }
      }
    });
  }

  ok() {
    this.fileInfo.description = this.formGroup.controls.description.value;
    this.dialogRef.close(this.fileInfo);
  }

}
