import { SystemAdminService } from 'src/app/services/system-admin.service';
import { TempFileInfo } from './../../advices/new-advice/new-advice.component';
import { MatchErrors } from './../../../users-profiles/profiles-admin/new-profile/new-profile.component';
import { EncService } from './../../../../services/enc/enc.service';
import { lastValueFrom } from 'rxjs';
import { MatSnackBar } from '@angular/material/snack-bar';
import { FormControl, Validators } from '@angular/forms';
import { Component, OnInit } from '@angular/core';
import { availableFiles } from 'src/environments/environment.prod';
import { MatTableDataSource } from '@angular/material/table';

@Component({
  selector: 'app-upload-catalogue',
  templateUrl: './upload-catalogue.component.html',
  styleUrls: ['./upload-catalogue.component.css']
})
export class UploadCatalogueComponent implements OnInit {
  catalogues: string[];
  fileData: any;
  fileName = "";
  fileSize = "";
  fileEmpty = true;
  sizeExceded = false;
  type = "";
  isUploading = false;
  isSaving = false;
  attached: TempFileInfo[];

  dataSource?: MatTableDataSource<TempFileInfo>;
  displayedColumns: string[] =  ['ID', 'NOMBRE', 'PESO', 'ACCIONES'];

  errorMatcher = new MatchErrors();
  catalogueType = new FormControl('', [Validators.required]);

  constructor(
    private _snackBar: MatSnackBar, 
    private _encService: EncService,
    private _systemAdminService: SystemAdminService,
  ) { 
    this.catalogues = ["Colonias", "Códigos postales", "Estados", "Localidades", "Municipios"];
    this.attached = [];
  }

  openSnackBar(msg: string){
    this._snackBar.open(msg, undefined, {
      duration: 2500
    });
  }

  ngOnInit(): void {
    this.dataSource = new MatTableDataSource(this.attached);
  }

  checkFile(event: any){
    let fileTypes = availableFiles;
    let sizes = Object.keys(fileTypes);
    let extensions = Object.values(fileTypes);
      
    let extArr = event.target.files[0].name.split(".").reverse();
    let extStr = extArr[0];

    if(extStr == 'xls' ||  extStr == 'xlsx'){
      let maxFileSize = 1048576 * 75;
      let fileSize = event.target.files[0].size;

      if(fileSize > maxFileSize){
        this.openSnackBar(`El tamaño del archivo supera el límite de 75 MB`);
      }else{
        let alreadyAttached = false;
        this.attached.forEach(file => {
          alreadyAttached = file.name == event.target.files[0].name && file.size == this.formatBytes(event.target.files[0].size);
        });

        if(alreadyAttached){
          this.openSnackBar("El archivo seleccionado ya fue adjuntado.");
        }else{
          this.isUploading = true;
          this.uploadTmp(event.target.files[0]);
        }
      }
    }else{
      this.openSnackBar('El archivo seleccionado no tiene el formato de Excel');
    }
  }

  async deleteFile(id: string){
    try{
      let idUser = localStorage.getItem('idusuario');
      let idUserShort = await lastValueFrom(this._encService.shortEncrypt(idUser!));

      let response = await lastValueFrom(this._systemAdminService.deleteTempFile({
        'id_user': idUserShort.response.encrypted,
        'id_file': id,
        'linea': 1,
      }));

      if(response.error){
        this.openSnackBar(response.msg);
      }else{
        let attachedAux: TempFileInfo[] = [];
        this.attached.forEach(file => {
          if(file.id != id) attachedAux.push(file);
        });

        this.attached = attachedAux;
        this.dataSource = new MatTableDataSource(this.attached);
      }
    }catch(error: any){
      this.isUploading = false;
      let msg = "";
      if(error.error == undefined){
        msg = 'Ocurrió un error insperado.';
      }else if(error.error.msg == undefined){
        msg = 'Ocurrió un error insperado.';
      }else{
        msg = error.error.msg;
      }

      this.openSnackBar(msg);
    }
  }

  formatBytes(bytes: number, decimals = 2) {
    if (bytes === 0) return '0 Bytes';

    const k = 1024;
    const dm = decimals < 0 ? 0 : decimals;
    const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];

    const i = Math.floor(Math.log(bytes) / Math.log(k));

    return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
  }

  async uploadTmp(fileData: any){
    try{
      let idUser = localStorage.getItem('idusuario');
      let idUserShort = await lastValueFrom(this._encService.shortEncrypt(idUser!));

      var myFormData = new FormData();
      myFormData.append('file', fileData);
      myFormData.append('id_user', idUserShort.response.encrypted);
      myFormData.append('linea', "1");

      let response = await lastValueFrom(this._systemAdminService.uploadTempFile(myFormData));
      if(response.error){
        this.openSnackBar(response.msg);
      }else{
        let uploadedFile: TempFileInfo = {
          id: response.response.idArchivo,
          name: fileData.name,
          size: this.formatBytes(fileData.size),
        };
        
        this.attached = [];
        this.attached.push(uploadedFile);
        this.dataSource = new MatTableDataSource(this.attached);
        this.isUploading = false;
      }
    }catch(error: any){
      this.isUploading = false;
      let msg = "";
      if(error.error == undefined){
        msg = 'Ocurrió un error insperado.';
      }else if(error.error.msg == undefined){
        msg = 'Ocurrió un error insperado.';
      }else{
        msg = error.error.msg;
      }

      this.openSnackBar(msg);
    }
  }

  async saveCatalogue(){
    try{
      if(this.attached.length == 0){
        this.openSnackBar('Aún no ha seleccionado ningún archivo adjunto.');
        return;
      }

      if(this.catalogueType.invalid){
        this.catalogueType.markAsTouched();
        return;
      }

      let attachedStr = JSON.stringify(this.attached);
      let idUser = localStorage.getItem('idusuario');
      let type = this.catalogueType.value;
      let body = new FormData();

      body.append('id_user', idUser!);
      body.append('linea', '1');
      body.append('tipo', type!);
      body.append('adjuntos', attachedStr);

      this.isSaving = true;
      await lastValueFrom(this._systemAdminService.saveCatalogue(body));
      this.isSaving = false;

      this.openSnackBar('El catálogo se registró correctamente')
      let close: HTMLElement = document.getElementById('close-button') as HTMLElement;
      close.click();
    }catch(error: any){
      if(error.error == undefined){
        this.openSnackBar('Ocurrió un error inesperado.');
      }else if(error.error.msg == undefined){
        this.openSnackBar('Ocurrió un error inesperado.');
      }else{
        this.openSnackBar(error.error.msg);
      }

      this.isSaving = false;
    }
  }
}
