import { HttpErrorResponse } from '@angular/common/http';
import {
  Component,
  ViewChild,
  OnInit,
  ElementRef,
} from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { lastValueFrom } from 'rxjs';
import { EncService } from 'src/app/services/enc/enc.service';
import { ResourcesService } from 'src/app/services/resources/resources.service';
import { ActivatedRoute } from '@angular/router';
import { MatSnackBar } from '@angular/material/snack-bar';
import {
  availableFiles,
  docClassification,
} from 'src/environments/environment.prod';
import { MatchErrors } from '../../users-profiles/profiles-admin/new-profile/new-profile.component';
import { FormControl, Validators } from '@angular/forms';
import { DocumentManagementService } from 'src/app/services/gdel/document-management.service';
import { GETBGMService } from 'src/app/services/getb/getbgm/getbgm.service';
import { UsersProfilesService } from 'src/app/services/users-profiles.service';
import { UsersResponse } from 'src/app/interfaces/users.interface';
import { ProfilesResponse } from 'src/app/interfaces/profiles.interface';
export interface TempFileInfo {
  id: string;
  name: string;
  size: string;
}
export interface Division {
  value: string;
  viewValue: string;
}
export interface ModuloResponse {
  CODIGO_MODULO: string;
  MODULO: string;
  FECHA_REG: string;
  FECHA_MOD: string;
  ESTADO: string;
}
export interface ResponseData {
  error: boolean;
  msg: string;
  response: Array<ModuloResponse>;
}
export interface DivisionGroup {
  name: string;
  division: Division[];
}
@Component({
  selector: 'app-addo',
  templateUrl: './addo.component.html',
  styleUrls: ['./addo.component.css'],
})
export class ADDOComponent implements OnInit {
  public isLoading: boolean;
  public hasError: boolean;
  public errorStr: String;
  public actionForm: String;
  public isNew: boolean;
  public idDocument: String;
  public isUploading: boolean;
  public downloadLink: String;
  public docClassificationAux: any;
  public modules: any;
  public arr_submodulo: any;
  public divisions: DivisionGroup[];
  public attached: TempFileInfo[];

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

  @ViewChild(MatPaginator) paginator?: MatPaginator;
  @ViewChild(MatSort) sort?: MatSort;
  @ViewChild('download') a?: ElementRef;

  errorMatcher = new MatchErrors();
  AFAL_NOAR = new FormControl('', [
    Validators.required,
    Validators.minLength(8),
    Validators.maxLength(100),
  ]);
  AFAL_CLDO = new FormControl('', Validators.required);
  AFAL_COMO = new FormControl('', Validators.required);
  AFAL_USAC = new FormControl('');

  constructor(
    private _encService: EncService,
    private _resourcesServices: ResourcesService,
    private _moduloService: GETBGMService,
    private _routeActivated: ActivatedRoute,
    private _snackBar: MatSnackBar,
    private _documentManagement: DocumentManagementService,
    private _usersProfilesService: UsersProfilesService
  ) {
    this.isNew = false;
    this.isLoading = true;
    this.hasError = false;
    this.errorStr = '';
    this.idDocument = '';
    this.actionForm = 'Crear Documento';
    this.isUploading = false;
    this.attached = [];
    this.modules = [];
    this.arr_submodulo = [];
    this.downloadLink = '';
    this.docClassificationAux = docClassification;
    this.divisions = [];
  }

  ngOnInit(): void {
    this.consultarModulos();
    this._routeActivated.queryParams.subscribe((params) => {
      let idDoc = params['idDoc'];
      this.isNew = idDoc == undefined;
      if (this.isNew) {
        this.getData();
      } else {
        this.idDocument = idDoc;
        //this.getAdvice(idAvi);
      }
    });
    this.isLoading = false;
  }

  async getData() {
    try {
      let idEnc = localStorage.getItem('idusuario')!;
      let idDec = await this._encService.desencriptar(idEnc);
      let shortEnc = await lastValueFrom(this._encService.shortEncrypt(idEnc));

      let users: UsersResponse = await lastValueFrom(
        this._usersProfilesService.getUsers(shortEnc.response.encrypted, 1)
      );
      this.errorStr = users.msg;
      this.hasError = users.error;

      if (this.hasError) {
        this.isLoading = false;
      } else {
        let profiles: ProfilesResponse = await lastValueFrom(
          this._usersProfilesService.getProfiles(shortEnc.response.encrypted, 1)
        );
        this.errorStr = profiles.msg;
        this.hasError = profiles.error;

        if (this.hasError) {
          this.isLoading = false;
        } else {
          let profilesGroup: DivisionGroup = {
            name: 'Perfiles',
            division: [],
          };

          profiles.response.forEach((profile) => {
            let profileDisplay: Division = {
              value: `prof-${profile.IDPERFIL}`,
              viewValue: profile.NOMBREPERFIL,
            };

            if (profile.ESTATUS != 'Eliminado')
              profilesGroup.division.push(profileDisplay);
          });

          this.divisions.push(profilesGroup);

          let usersGroup: DivisionGroup = {
            name: 'Usuarios',
            division: [],
          };

          users.response.forEach((user) => {
            let userName = this.buildName(
              user.NOMBRE,
              user.APEPAT,
              user.APEMAT
            );
            let userID = `user-${user.IDUSUARIO}`;

            let userDisplay: Division = {
              value: userID,
              viewValue: userName,
            };

            if (user.IDUSUARIO != idDec) {
              if (user.ESTATUS == 'Activo')
                usersGroup.division.push(userDisplay);
            }
          });

          this.divisions.push(usersGroup);

          if (this.isNew) {
            let initialFiles: TempFileInfo[] = [];
            this.dataSource = new MatTableDataSource(initialFiles);
          }

          this.isLoading = false;
        }
      }
    } catch (error: any) {
      this.isLoading = false;
      this.hasError = true;

      if (error.error == undefined || error.error == null) {
        this.errorStr = 'Ocurrió un error inesperado.';
      } else if (error.error.msg == undefined || error.error.msg == null) {
        this.errorStr = 'Ocurrió un error inesperado.';
      } else {
        this.errorStr = error.error.msg;
      }
    }

    console.log(this.divisions);
    
  }

  checkFile(event: any) {
    let fileTypes = availableFiles;
    let sizes = Object.keys(fileTypes);
    let extensions = Object.values(fileTypes);
    let maxSizeMB = 0;

    let extArr = event.target.files[0].name.split('.').reverse();
    let extStr = extArr[0];

    let i = 0;
    extensions.forEach((ext) => {
      let size = parseInt(sizes[i]);

      if (ext.includes(extStr)) maxSizeMB = size;
      i++;
    });

    if (maxSizeMB == 0) {
      this.openSnackBar(`Los archivos ${extStr} no están soportados`);
    } else {
      let maxFileSize = 1048576 * maxSizeMB;
      let fileSize = event.target.files[0].size;

      if (fileSize > maxFileSize) {
        this.openSnackBar(
          `El tamaño del archivo supera el límite de ${maxSizeMB} 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]);
        }
      }
    }
  }

  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._documentManagement.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.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 deleteFile(id: string) {
    try {
      let idUser = localStorage.getItem('idusuario');
      let idUserShort = await lastValueFrom(
        this._encService.shortEncrypt(idUser!)
      );

      let response = await lastValueFrom(
        this._documentManagement.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);
    }
  }

  async downloadFile(idFile: string) {
    /*     try{
      let shortAvi = await lastValueFrom(this._encService.shortEncrypt(idFile));
      let idEnc = localStorage.getItem('idusuario');
      let shortEnc = await lastValueFrom(this._encService.shortEncrypt(idEnc!));

      let downloadToken = await lastValueFrom(this._advicesService.getDownloadToken(shortAvi.response.encrypted, shortEnc.response.encrypted, 1));
      //this.downloadLink = "http://git.ittec.mx/sam/public/api/download-file///1";
      this.downloadLink = `http://git.ittec.mx/sam/public/api/download-file/${downloadToken.response.TOKEN}/${shortEnc.response.encrypted}/1`;
      console.log(this.downloadLink);
      this.a?.nativeElement.click();
    }catch(error: any){
      let msg = '';
      if(error.error == undefined){
        msg = 'Ocurrió un error inesperado.';
      }else if(error.error.msg == undefined){
        msg = 'Ocurrió un error inesperado.';
      }else{
        msg = error.error.msg;
      }

      this.openSnackBar(msg);
    } */
  }

  public async consultarModulos() {
    this.isLoading = true;
    await lastValueFrom(this._moduloService.getModules()).then(
      (data: ResponseData) => {
        console.log(data.response);

        this.modules = data.response;
      },
      (error: HttpErrorResponse) => this._resourcesServices.checkErrors(error)
    );
    this.isLoading = false;
  }

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

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

  buildName(nomb: string, appa: string, apma?: string): string {
    if (apma == '' || apma == null || apma == undefined) {
      return `${nomb} ${appa}`;
    } else {
      return `${nomb} ${appa} ${apma}`;
    }
  }

  public goBack(steps: number) {
    window.history.go(steps * -1);
  }
}
