import { Component, Inject, OnInit } from '@angular/core';
import { EquipmentDetails, EquipmentDetailsResponse, EquipmentsListItem, EquipmentsListResponse, FamiliesListItem, FamiliesListResponse, HistorialCodigos, PendingEquipmentsListItem, PendingEquipmentsListResponse, SubfamiliesListItem, SubfamiliesListResponse } from '../../interfaces/equipment-management.interface';
import { PriorityInterface } from '../system-admin/system-params/system-params.component';
import { DOCUMENT } from '@angular/common';
import { ActivatedRoute, Router } from '@angular/router';
import { MatDialog } from '@angular/material/dialog';
import { EquipmentManagementService } from '../../services/equipment-management.service';
import { EncService } from '../../services/enc.service';
import { FunctionsService } from '../../services/functions.service';
import { ResourcesService } from '../../services/resources.service';
import { GdelService } from '../../services/gdel.service';
import { SystemAdminService } from '../../services/system-admin.service';
import { SocketService } from '../../services/socket.service';
import { UsersProfilesService } from '../../services/users-profiles.service';
import { UserConsultResponse } from '../../interfaces/user.interface';
import { lastValueFrom } from 'rxjs';
import { ProfileInterface } from '../../interfaces/profile.interface';
import { Permissions } from '../../interfaces/permissions.interface';
import { LocationsManagementComponent } from './locations-management/locations-management.component';
import { OccupationManagementComponent } from './occupation-management/occupation-management.component';
import { ArborescenceViewComponent } from './arborescence-view/arborescence-view.component';
import { GroupPendingComponent } from './group-pending/group-pending.component';

const ID_MODULE = "S002V01M07GEEQ";
@Component({
    selector: 'app-equipment-management',
    templateUrl: './equipment-management.component.html',
    styleUrl: './equipment-management.component.css',
    standalone: false
})
export class EquipmentManagementComponent implements OnInit {
  isLoading: boolean;
  hasError: boolean;
  errorStr: string;
  params: any;
  totalPending: number;
  loadingPending: boolean;

  pendingEquipments: PendingEquipmentsListItem[];
  families: FamiliesListItem[];
  subfamilies: SubfamiliesListItem[];
  equipmentsBySubfamily: EquipmentsListItem[];

  currentLevel: number;
  equipmentStates = {DE: 'Detenido', DP: 'Detenido parcialmente', EF: 'En funcionamiento'};
  parentEquipmentDetails: EquipmentDetails | null;
  codeTypes: Map<string, string>;
  arborescence: string[];
  graphicArborescence: any[];
  priorities: PriorityInterface[];

  equipmentsMenuEnabled: boolean;
  equipmentDetailsEnabled: boolean;
  equipmentImagesGalleryEnabled: boolean;
  relatedDocumentsTableEnabled: boolean;
  equivalentEquipmentsTableEnabled: boolean;
  lastMeasuresTableEnabled: boolean;
  movementsHistoryEnabled: boolean;
  equipmentRecordsTableEnabled: boolean;
  moveEquipmentEnabled: boolean;
  copyEquipmentEnabled: boolean;
  addEquipmentEnabled: boolean;
  equipmentTypeManagementEnabled: boolean;
  equipmentLocationEnabled: boolean;
  viewArborescenceInData: boolean;
  securityCriticalityEnabled: boolean;

  constructor(
    @Inject(DOCUMENT) private _document: Document,
    private _router: Router,
    private _dialog: MatDialog,
    private _equipmentManagementService: EquipmentManagementService,
    private _encService: EncService,
    private _activatedRoute: ActivatedRoute,
    private _functionsService: FunctionsService,
    private _resourcesService: ResourcesService,
    private _gdelService: GdelService,
    private _sysAdminService: SystemAdminService,
    private _socketService: SocketService,
    private _usersProfilesService: UsersProfilesService,
  ) { 
    this._functionsService.consultModuleStatus(ID_MODULE);
    this.isLoading = true;
    this.hasError = false;
    this.errorStr = "";
    this.params = null;
    this.totalPending = 0;
    this.loadingPending = false;

    this.pendingEquipments = [];
    this.families = [];
    this.subfamilies = [];
    this.equipmentsBySubfamily = [];

    this.currentLevel = 1;
    this.parentEquipmentDetails = null;
    this.codeTypes = new Map([
      ['1', 'General'],
      ['2', 'PCC'],
      ['3', 'Origen y destino para líneas y enlaces'],
      ['4', 'Origen y destino para estaciones y edificios'],
      ['5', 'Tren'],
      ['6', 'Origen y destino mixto'],
    ]);

    this.arborescence = ['Línea 1'];
    this.graphicArborescence = [{
      label: 'Línea 1',
      graph: 'logo',
    }];

    this.priorities = [];

    this.equipmentsMenuEnabled = true;
    this.equipmentDetailsEnabled = true;
    this.equipmentImagesGalleryEnabled = true;
    this.relatedDocumentsTableEnabled = true;
    this.equivalentEquipmentsTableEnabled = true;
    this.lastMeasuresTableEnabled = true;
    this.movementsHistoryEnabled = true;
    this.equipmentRecordsTableEnabled = true;
    this.moveEquipmentEnabled = true;
    this.copyEquipmentEnabled = true;
    this.addEquipmentEnabled = true;
    this.equipmentTypeManagementEnabled = true;
    this.equipmentLocationEnabled = true;
    this.viewArborescenceInData = true;
    this.securityCriticalityEnabled = true;
  }

  ngOnInit(): void {
    this._activatedRoute.queryParams.subscribe(params => {
      this.params = params;
      this.init(params);
    });

    this._socketService.refreshPermissions().subscribe(async (profUpdEnc) => {
      try{
        let idUser = localStorage.getItem('idusuario')!;
        let usrInfo: UserConsultResponse = await lastValueFrom(this._usersProfilesService.getUser(idUser, idUser, 1));
        
        if(usrInfo.error){
          this._resourcesService.openSnackBar('Ocurrió un error inesperado (1).');
        }else{
          let idProfDec = await this._encService.decrypt(usrInfo.response.PERFIL);
          let currentProfile = await this._encService.decrypt(localStorage.getItem('perfil')!);

          if(idProfDec != currentProfile){
            this._router.navigate(['/sam/home']);
            return;
          }
          
          let profileUpdated = await this._encService.decrypt(`${profUpdEnc}`);
          if(profileUpdated == currentProfile){
            let profile = localStorage.getItem('perfil')!;
            let profInfo: ProfileInterface = await lastValueFrom(this._usersProfilesService.getProfile(
              profile,
              idUser,
              1
            ));

            let permArr = await this._functionsService.processPermissions(profInfo.response.PERMISOS.permissions);
            let modPerm = permArr.filter(item => item.id == 'S002V01M07GEEQ');
            if(modPerm.length > 0){
              let funPerm = modPerm[0].children.filter(item => item.id == 'S002V01F01ADEQ');
              if(funPerm.length > 0){
                let equipmentsMenuEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P01MEEQ');
                if(equipmentsMenuEnabled.length > 0){
                  this.equipmentsMenuEnabled = equipmentsMenuEnabled[0].access > 0;
                }
            
                let equipmentDetailsEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P02DEEQ');
                if(equipmentDetailsEnabled.length > 0){
                  this.equipmentDetailsEnabled = equipmentDetailsEnabled[0].access > 0;
                }
                
                let equipmentImagesGalleryEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P03GIEQ');
                if(equipmentImagesGalleryEnabled.length > 0){
                  this.equipmentImagesGalleryEnabled = equipmentImagesGalleryEnabled[0].access > 0;
                }
                
                let relatedDocumentsTableEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P04TDRE');
                if(relatedDocumentsTableEnabled.length > 0){
                  this.relatedDocumentsTableEnabled = relatedDocumentsTableEnabled[0].access > 0;
                }
                
                let equivalentEquipmentsTableEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P05TEEQ');
                if(equivalentEquipmentsTableEnabled.length > 0){
                  this.equivalentEquipmentsTableEnabled = equivalentEquipmentsTableEnabled[0].access > 0;
                }
    
                let lastMeasuresTableEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P06TUME');
                if(lastMeasuresTableEnabled.length > 0){
                  this.lastMeasuresTableEnabled = lastMeasuresTableEnabled[0].access > 0;
                }
    
                let movementsHistoryEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P07HIMO');
                if(movementsHistoryEnabled.length > 0){
                  this.movementsHistoryEnabled = movementsHistoryEnabled[0].access > 0;
                }
    
                let equipmentRecordsTableEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P08TFEQ');
                if(equipmentRecordsTableEnabled.length > 0){
                  this.equipmentRecordsTableEnabled = equipmentRecordsTableEnabled[0].access > 0;
                }
    
                let moveEquipmentEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P09MOEQ');
                if(moveEquipmentEnabled.length > 0){
                  this.moveEquipmentEnabled = moveEquipmentEnabled[0].access > 0;
                }
    
                let copyEquipmentEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P10COEQ');
                if(copyEquipmentEnabled.length > 0){
                  this.copyEquipmentEnabled = copyEquipmentEnabled[0].access > 0;
                }
    
                let addEquipmentEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P11REEQ');
                if(addEquipmentEnabled.length > 0){
                  this.addEquipmentEnabled = addEquipmentEnabled[0].access > 0;
                }
    
                let equipmentTypeManagementEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P12GCTE');
                if(equipmentTypeManagementEnabled.length > 0){
                  this.equipmentTypeManagementEnabled = equipmentTypeManagementEnabled[0].access > 0;
                }
    
                let equipmentLocationEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P13LOEQ');
                if(equipmentLocationEnabled.length > 0){
                  this.equipmentLocationEnabled = equipmentLocationEnabled[0].access > 0;
                }
    
                let viewArborescenceInData = funPerm[0].children.filter(item => item.id == 'S002V01P14VAFD');
                if(viewArborescenceInData.length > 0){
                  this.viewArborescenceInData = viewArborescenceInData[0].access > 0;
                }
              }

              let securityCriticalityEnabled = modPerm[0].children.filter(item => item.id == 'S002V01F03GCSE');
              if(securityCriticalityEnabled.length > 0){
                this.securityCriticalityEnabled = securityCriticalityEnabled[0].access > 0;
              }
            }
          }
        }
      }catch(error: any){
        if(error.error == undefined){
          this._resourcesService.openSnackBar('ERR_PAD001: Ocurrió un error inesperado (2).');
        }else if(error.error.msg == undefined){
          this._resourcesService.openSnackBar('ERR_PAD002: Ocurrió un error inesperado (3).');
        }else{
          this._resourcesService.openSnackBar(`ERR_PAD003: ${error.error.msg}`);
        }
      }
    });

    this._socketService.refreshModules().subscribe(async () => this._functionsService.consultModuleStatus(ID_MODULE));
  }

  async init(params: any){
    try{
      let permissionsEnc = localStorage.getItem('permisos');
      let permissionsDec = '';
      if(permissionsEnc == '' || permissionsEnc == undefined || permissionsEnc == null){
        permissionsDec = '[]';
      }else{
        permissionsDec = await this._encService.decrypt(permissionsEnc!);
      }
  
      let permissionsArr: Permissions = JSON.parse(permissionsDec);
      if(permissionsArr.permissions != undefined){
        let modPerm = permissionsArr.permissions.filter(item => item.id == 'S002V01M07GEEQ');
        if(modPerm.length > 0){
          let funPerm = modPerm[0].children.filter(item => item.id == 'S002V01F01ADEQ');
          if(funPerm.length > 0){
            let equipmentsMenuEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P01MEEQ');
            if(equipmentsMenuEnabled.length > 0){
              this.equipmentsMenuEnabled = equipmentsMenuEnabled[0].access > 0;
            }
            
            let equipmentDetailsEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P02DEEQ');
            if(equipmentDetailsEnabled.length > 0){
              this.equipmentDetailsEnabled = equipmentDetailsEnabled[0].access > 0;
            }
            
            let equipmentImagesGalleryEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P03GIEQ');
            if(equipmentImagesGalleryEnabled.length > 0){
              this.equipmentImagesGalleryEnabled = equipmentImagesGalleryEnabled[0].access > 0;
            }
            
            let relatedDocumentsTableEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P04TDRE');
            if(relatedDocumentsTableEnabled.length > 0){
              this.relatedDocumentsTableEnabled = relatedDocumentsTableEnabled[0].access > 0;
            }
            
            let equivalentEquipmentsTableEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P05TEEQ');
            if(equivalentEquipmentsTableEnabled.length > 0){
              this.equivalentEquipmentsTableEnabled = equivalentEquipmentsTableEnabled[0].access > 0;
            }

            let lastMeasuresTableEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P06TUME');
            if(lastMeasuresTableEnabled.length > 0){
              this.lastMeasuresTableEnabled = lastMeasuresTableEnabled[0].access > 0;
            }

            let movementsHistoryEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P07HIMO');
            if(movementsHistoryEnabled.length > 0){
              this.movementsHistoryEnabled = movementsHistoryEnabled[0].access > 0;
            }

            let equipmentRecordsTableEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P08TFEQ');
            if(equipmentRecordsTableEnabled.length > 0){
              this.equipmentRecordsTableEnabled = equipmentRecordsTableEnabled[0].access > 0;
            }

            let moveEquipmentEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P09MOEQ');
            if(moveEquipmentEnabled.length > 0){
              this.moveEquipmentEnabled = moveEquipmentEnabled[0].access > 0;
            }

            let copyEquipmentEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P10COEQ');
            if(copyEquipmentEnabled.length > 0){
              this.copyEquipmentEnabled = copyEquipmentEnabled[0].access > 0;
            }

            let addEquipmentEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P11REEQ');
            if(addEquipmentEnabled.length > 0){
              this.addEquipmentEnabled = addEquipmentEnabled[0].access > 0;
            }

            let equipmentTypeManagementEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P12GCTE');
            if(equipmentTypeManagementEnabled.length > 0){
              this.equipmentTypeManagementEnabled = equipmentTypeManagementEnabled[0].access > 0;
            }

            let equipmentLocationEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P13LOEQ');
            if(equipmentLocationEnabled.length > 0){
              this.equipmentLocationEnabled = equipmentLocationEnabled[0].access > 0;
            }

            let viewArborescenceInData = funPerm[0].children.filter(item => item.id == 'S002V01P14VAFD');
            if(viewArborescenceInData.length > 0){
              this.viewArborescenceInData = viewArborescenceInData[0].access > 0;
            }
          }

          let securityCriticalityEnabled = modPerm[0].children.filter(item => item.id == 'S002V01F03GCSE');
          if(securityCriticalityEnabled.length > 0){
            this.securityCriticalityEnabled = securityCriticalityEnabled[0].access > 0;
          }
        }
      }
  
      this.arborescence = ['Línea 1'];
      this.graphicArborescence = [{
        label: 'Línea 1',
        graph: 'logo',
      }];
  
      this.isLoading = true;
      this.hasError = false;
      this.errorStr = "";
  
      let family = params['family'];
      if(family == undefined){
        this.currentLevel = 1;
        this.getFamilies(true);
        return;
      }
  
      await this.getFamilies(false);
      let familyDec = await this._encService.decrypt(family);
      for(const familyObj of this.families){
        let familyCodeDec = await this._encService.decrypt(familyObj.CODIGOFAMILIA);
        if(familyDec == familyCodeDec){
          this.arborescence.push(familyObj.NOMBREFAMILIA);
          this.graphicArborescence.push({
            label: familyObj.NOMBREFAMILIA,
            graph: JSON.stringify({icon: familyObj.ICONO, customIcon: familyObj.ICONO_PERSONALIZADO}),
          });
        }
      }
  
      let subfamily = params['subfamily'];
      if(subfamily == undefined){
        this.currentLevel = 2;
        this.getSubfamilies(family, true);
        return;
      }
  
      await this.getSubfamilies(family, false);
      let subfamilyDec = await this._encService.decrypt(subfamily);
      for(const subfamilyObj of this.subfamilies){
        let subfamilyCodeDec = await this._encService.decrypt(subfamilyObj.CODIGOSUBFAMILIA);
        if(subfamilyCodeDec == subfamilyDec){
          this.arborescence.push(subfamilyObj.NOMBRESUBFAMILIA);
          this.graphicArborescence.push({
            label: subfamilyObj.NOMBRESUBFAMILIA,
            graph: JSON.stringify({icon: subfamilyObj.ICONO, customIcon: subfamilyObj.ICONO_PERSONALIZADO}),
          });
        }
      }
  
      let arborescence = params['arborescence'];
      if(arborescence == undefined){
        this.currentLevel = 3;
        this.getEquipmentsBySubfamily(family, subfamily, true);
        return;
      }
  
      let arborescenceStr = window.atob(arborescence);
      let arborescenceArr = JSON.parse(arborescenceStr);
      let arborescenceArrAux = JSON.parse(arborescenceStr);
  
      arborescenceArr.reverse();
      let lastParent = arborescenceArr[0];
      arborescenceArr.reverse();
      
      await this.getEquipmentsBySubfamily(family, subfamily, false);
      let firstParentDec = await this._encService.decrypt(arborescenceArr[0]);
      for(const equipmentObj of this.equipmentsBySubfamily){
        let equipmentCodeDec = await this._encService.decrypt(equipmentObj.CODIGO);
        if(equipmentCodeDec == firstParentDec){
          this.arborescence.push(`${equipmentCodeDec} - ${equipmentObj.TIPO} - ${equipmentObj.MODELO}`);
          
          let firstImage = equipmentObj.GALERIA_IMAGENES![0];
          this.graphicArborescence.push({
            label: `${equipmentCodeDec} - ${equipmentObj.TIPO} - ${equipmentObj.MODELO}`,
            graph: firstImage
          });
        }
      }
  
      if(arborescenceArr.length > 1){
        arborescenceArrAux.reverse();
        arborescenceArrAux.pop();
        arborescenceArrAux.reverse();
  
        let arborescenceArrDec = [];
        for(const item of arborescenceArrAux){
          let itemDec = await this._encService.decrypt(item);
          arborescenceArrDec.push(itemDec);
        }
  
        arborescenceArr.pop();
        for(const item of arborescenceArr){
          await this.getEquipmentsByParent(item, false);
  
          for(const childObj of this.equipmentsBySubfamily){
            let childCodeDec = await this._encService.decrypt(childObj.CODIGO);
            let itemFilt = arborescenceArrDec.filter(option => option.toUpperCase() == childCodeDec.toUpperCase());
  
            if(itemFilt.length > 0){
              this.arborescence.push(`${childCodeDec} - ${childObj.TIPO} - ${childObj.MODELO}`);
          
              let firstImage = childObj.GALERIA_IMAGENES![0];
              this.graphicArborescence.push({
                label: `${childCodeDec} - ${childObj.TIPO} - ${childObj.MODELO}`,
                graph: firstImage
              });
            }
          }
        }
      }
  
      this.currentLevel = 4;
      this.getEquipmentsByParent(lastParent, true);
    }catch(error: any){
      console.log(error);
    }
  }

  async getFamilies(searchPending: boolean){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let families: FamiliesListResponse = await lastValueFrom(this._equipmentManagementService.familyConsult(idUser, 1));

      this.hasError = families.error;
      this.errorStr = families.msg;

      if(this.hasError){
        this.isLoading = false;
      }else{
        let familiesArr: FamiliesListItem[] = [];
        for(const family of families.response){
          let codeDec = await this._encService.decrypt(family.CODIGOFAMILIA);
          family.NOMBREFAMILIA = `${family.NOMBREFAMILIA} (${codeDec})`;

          if(family.ARCHIVO_ICONO != null){
            let iconURI = await lastValueFrom(this._gdelService.getPublicDocumentUrl(family.ARCHIVO_ICONO, idUser, 1));
            family.URL_ICONO = iconURI.response.public_uri;
          }else{
            family.URL_ICONO = '';
          }

          if(family.ESTADO == 'Activo'){
            familiesArr.push(family);
          }
        }

        this.families = familiesArr;
        if(searchPending){
          this.getTotalPendingEquipments();
        }
      }
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado (4).';
      }else if(error.error.msg == undefined){
        console.log(error);
        
        this.errorStr = 'Ocurrió un error inesperado (5).';
      }else{
        this.errorStr = error.error.msg;
      }
      this.hasError = true;
      this.isLoading = false;
    }
  }

  async getTotalPendingEquipments(){
    try{
      this.isLoading = true;
      this.hasError = false;
      this.errorStr = '';
      this.totalPending = 0;
      this.pendingEquipments = [];

      let idUser = localStorage.getItem('idusuario')!;
      let pendingTotal = await lastValueFrom(this._equipmentManagementService.equipmentConsultPendingTotal(idUser, 1));
      
      this.hasError = pendingTotal.error;
      this.errorStr = pendingTotal.msg;

      if(!this.hasError){
        this.totalPending = pendingTotal.response.TOTAL;
        this.consultPendingEquipments(0);
      }
      
      this.isLoading = false;
      this.scrollArborescence();
      this.addPendingEquipmentsScrollListener();
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado (6).';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado (7).';
      }else{
        this.errorStr = error.error.msg;
      }
      this.hasError = true;
      this.isLoading = false;
    }
  }

  private async consultPendingEquipments(offset: number){
    try{
      this.loadingPending = true;

      let idUser = localStorage.getItem('idusuario')!;
      let pendingEquipments: PendingEquipmentsListResponse = await lastValueFrom(this._equipmentManagementService.equipmentConsultPending(
        offset,
        idUser, 
        1
      ));

      if(pendingEquipments.error){
        this._resourcesService.openSnackBar(pendingEquipments.msg);
      }else{
        for(const equipment of pendingEquipments.response){
          equipment.CODIGO = await this._encService.decrypt(equipment.CODIGO);
          equipment.TIPO_EQUIPAMIENTO = await this._encService.decrypt(equipment.TIPO_EQUIPAMIENTO);
          equipment.MODELO_EQUIPAMIENTO = await this._encService.decrypt(equipment.MODELO_EQUIPAMIENTO);

          let galleryArr = JSON.parse(equipment.GALERIA_IMAGENES as string);
          let gallery: string[] = [];
          for(const imageStr of galleryArr){
            let imageDec = await this._encService.decrypt(imageStr);
            gallery.push(imageDec);
          }

          equipment.GALERIA_IMAGENES = gallery;
          this.pendingEquipments.push(equipment);
        }
      }

      this.loadingPending = false;
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (8).');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (9).');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }

      this.loadingPending = false;
    }
  }

  scrollArborescence(){
    setTimeout(() => {
      let scroll = this._document.getElementById('arborescence-scroll')!;
      scroll.scrollLeft = scroll.scrollWidth;

      scroll.addEventListener('wheel', (e: any) => {
        if(e.deltaY > 0){
          scroll.scrollLeft += 25;
          e.preventDefault();
        }else{
          scroll.scrollLeft -= 25;
          e.preventDefault();
        }
      });
    }, 150);
  }

  addPendingEquipmentsScrollListener(){
    setTimeout(() => {
      let equipmentList = this._document.getElementById('pending-equipments-list')!;
      if(equipmentList != null && equipmentList != undefined){
        equipmentList.addEventListener('scroll', (event: any) => {
          let delta = equipmentList.scrollHeight - equipmentList.scrollTop;
          if(delta < 400 && !this.loadingPending){
            let offset = this.pendingEquipments.length;
            if(offset < this.totalPending){
              this.consultPendingEquipments(offset);
            }
          }
        });
      }
    });
  }

  async getSubfamilies(family: string, searchPending: boolean){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let subfamilies: SubfamiliesListResponse = await lastValueFrom(this._equipmentManagementService.subfamilyConsult(family, idUser, 1));

      this.hasError = subfamilies.error;
      this.errorStr = subfamilies.msg;

      if(this.hasError){
        this.isLoading = false;
      }else{
        let subfamiliesArr: SubfamiliesListItem[] = [];
        for(const subfamily of subfamilies.response){
          if(subfamily.ARCHIVO_ICONO != null){
            let iconURI = await lastValueFrom(this._gdelService.getPublicDocumentUrl(subfamily.ARCHIVO_ICONO, idUser, 1));
            subfamily.URL_ICONO = iconURI.response.public_uri;
          }else{
            subfamily.URL_ICONO = '';
          }
          
          let codeDec = await this._encService.decrypt(subfamily.CODIGOSUBFAMILIA);
          subfamily.NOMBRESUBFAMILIA = `${subfamily.NOMBRESUBFAMILIA} (${codeDec})`;

          if(subfamily.ESTADO == 'Activo'){
            subfamiliesArr.push(subfamily);
          }
        }

        this.subfamilies = subfamiliesArr;
        if(searchPending){
          this.getTotalPendingEquipments();
        }
      }
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado (10).';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado (11).';
      }else{
        this.errorStr = error.error.msg;
      }
      this.hasError = true;
      this.isLoading = false;
    }
  }

  async getEquipmentsBySubfamily(family: string, subfamily: string, searchPending: boolean){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let equipmentsBySubfamily: EquipmentsListResponse = await lastValueFrom(this._equipmentManagementService.equipmentConsultBySubfamily(
        family, 
        subfamily, 
        idUser, 
        1
      ));

      this.hasError = equipmentsBySubfamily.error;
      this.errorStr = equipmentsBySubfamily.msg;

      if(this.hasError){
        this.isLoading = false;
      }else{
        let equipments: EquipmentsListItem[] = [];
        for(const equipment of equipmentsBySubfamily.response){
          let idDec = await this._encService.decrypt(equipment.ID_EQUIPO);
          equipment.MODELO = `${equipment.MODELO} (${idDec})`;

          let functionState = this.equipmentStates[equipment.ESTADO_FUNCIONAMIENTO as never];
          equipment.ESTADO_FUNCIONAMIENTO = `${functionState} (${equipment.ESTADO_FUNCIONAMIENTO})`;

          let galleryArr = JSON.parse(equipment.GALERIA_IMAGENES as string);
          let images: string[] = [];
          for(const image of galleryArr){
            let uriDec = await this._encService.decrypt(image);
            images.push(uriDec);
          }

          equipment.GALERIA_IMAGENES = images;
          equipments.push(equipment);
        }

        this.equipmentsBySubfamily = equipments;
        if(searchPending){
          this.getTotalPendingEquipments();
        }
      }
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado (12).';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado (13).';
      }else{
        this.errorStr = error.error.msg;
      }

      this.hasError = true;
      this.isLoading = false;
    }
  }

  async getEquipmentsByParent(parent: string, searchPending: boolean){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let parentEquipments: EquipmentsListResponse = await lastValueFrom(this._equipmentManagementService.equipmentConsultByParent(
        parent, 
        idUser, 
        1
      ));

      this.hasError = parentEquipments.error;
      this.errorStr = parentEquipments.msg;

      if(this.hasError){
        this.isLoading = false;
      }else{
        let equipments: EquipmentsListItem[] = [];
        for(const equipment of parentEquipments.response){
          let idDec = await this._encService.decrypt(equipment.ID_EQUIPO);
          equipment.MODELO = `${equipment.MODELO} (${idDec})`;

          let functionState = this.equipmentStates[equipment.ESTADO_FUNCIONAMIENTO as never];
          equipment.ESTADO_FUNCIONAMIENTO = `${functionState} (${equipment.ESTADO_FUNCIONAMIENTO})`;

          let galleryArr = JSON.parse(equipment.GALERIA_IMAGENES as string);
          let images: string[] = [];
          for(const image of galleryArr){
            let uriDec = await this._encService.decrypt(image);
            images.push(uriDec);
          }

          equipment.GALERIA_IMAGENES = images;
          equipments.push(equipment);
        }

        this.equipmentsBySubfamily = equipments;
        if(searchPending){
          this.getOrderPriorities(parent);
        }
      }
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado (14).';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado (15).';
      }else{
        this.errorStr = error.error.msg;
      }

      this.hasError = true;
      this.isLoading = false;
    }
  }

  async getOrderPriorities(parent: string){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let priorities = await lastValueFrom(this._sysAdminService.getOrderPriorities(idUser, 1));

      this.hasError = priorities.error;
      this.errorStr = priorities.msg;

      if(this.hasError){
        this.isLoading = false;
      }else{
        let prioritiesArr: PriorityInterface[] = [];
        for(const priority of priorities.response.order_priorities as PriorityInterface[]){
          let valueEnc = await this._encService.encrypt(priority.value);

          priority.label = `${priority.label} (${priority.value})`;
          priority.value = valueEnc;

          prioritiesArr.push(priority);
        }

        this.priorities = prioritiesArr;
        this.getEquipmentDetails(parent);
      }
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado (16).';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado (17).';
      }else{
        this.errorStr = error.error.msg;
      }

      this.hasError = true;
      this.isLoading = false;
    }
  }

  async getEquipmentDetails(equipmentCode: string){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let equipment: EquipmentDetailsResponse = await lastValueFrom(this._equipmentManagementService.equipmentConsultOnly(
        equipmentCode,
        idUser, 
        1
      ));

      this.hasError = equipment.error;
      this.errorStr = equipment.msg;

      if(this.hasError){
        this.isLoading = false;
      }else{
        equipment.response.CODIGO = await this._encService.decrypt(equipment.response.CODIGO);
        equipment.response.DOCUMENTOS = JSON.parse(equipment.response.DOCUMENTOS as string);
        
        let images = JSON.parse(equipment.response.GALERIA_IMAGENES as string);
        let imagesArr: string[] = [];
        for(const image of images){
          let imageDec = await this._encService.decrypt(image);
          imagesArr.push(imageDec);
        }
        
        equipment.response.GALERIA_IMAGENES = imagesArr;

        let codeHistory: HistorialCodigos[] = JSON.parse(equipment.response.HISTORIAL_CODIGOS as string);
        for(const code of codeHistory){
          code.CODIGO = await this._encService.decrypt(code.CODIGO);
        }

        if(equipment.response.NIVEL_CRITICIDAD != null){
          let criticalityDec = await this._encService.decrypt(equipment.response.NIVEL_CRITICIDAD);
          for(const priority of this.priorities){
            let valueDec = await this._encService.decrypt(priority.value);
            if(valueDec == criticalityDec){
              equipment.response.NIVEL_CRITICIDAD_OBJ = priority;
            }
          }
        }

        if(equipment.response.SECUENCIA_ELEMENTO_ORIGEN != null){
          let originElementSequence = await this._encService.decrypt(equipment.response.SECUENCIA_ELEMENTO_ORIGEN);
          let originElementSequenceLength = originElementSequence.length;
          let originElementSequenceAux = '';

          for(let i = originElementSequenceLength; i < 6; i++){
            originElementSequenceAux += '0';
          }

          equipment.response.SECUENCIA_ELEMENTO_ORIGEN = `${originElementSequenceAux}${originElementSequence}`;
        }

        if(equipment.response.SECUENCIA_ELEMENTO_DESTINO != null){
          let destinyElementSequence = await this._encService.decrypt(equipment.response.SECUENCIA_ELEMENTO_DESTINO);
          let destinyElementSequenceLength = destinyElementSequence.length;
          let destinyElementSequenceAux = '';

          for(let i = destinyElementSequenceLength; i < 6; i++){
            destinyElementSequenceAux += '0';
          }

          equipment.response.SECUENCIA_ELEMENTO_DESTINO = `${destinyElementSequenceAux}${destinyElementSequence}`;
        }
        
        equipment.response.HISTORIAL_CODIGOS_ARR = codeHistory;
        equipment.response.ID_EQUIPAMIENTO = await this._encService.decrypt(equipment.response.ID_EQUIPAMIENTO);
        equipment.response.MODELO = await this._encService.decrypt(equipment.response.MODELO);
        
        equipment.response.TIPO_EQUIPAMIENTO = await this._encService.decrypt(equipment.response.TIPO_EQUIPAMIENTO);
        equipment.response.TIPO_CODIGO = `${this.codeTypes.get(equipment.response.TIPO_CODIGO)} (${equipment.response.TIPO_CODIGO})`;
        equipment.response.FECHA_ADQUISICION = this._functionsService.buildHumanDate(equipment.response.FECHA_ADQUISICION);
        equipment.response.FECHA_INICIO_GARANTIA = this._functionsService.buildHumanDate(equipment.response.FECHA_INICIO_GARANTIA);
        equipment.response.FECHA_TERMINO_GARANTIA = this._functionsService.buildHumanDate(equipment.response.FECHA_TERMINO_GARANTIA);
        equipment.response.ESTADO_FUNCIONAMIENTO = this.equipmentStates[equipment.response.ESTADO_FUNCIONAMIENTO as never];
        equipment.response.FECHA_REGISTRO = this._functionsService.orderDate(equipment.response.FECHA_REGISTRO);

        if(equipment.response.TIPO_CODIFICACION_ORIGEN != null){
          equipment.response.TIPO_CODIFICACION_ORIGEN = `${this.codeTypes.get(equipment.response.TIPO_CODIFICACION_ORIGEN)} (${equipment.response.TIPO_CODIFICACION_ORIGEN})`;
        }

        if(equipment.response.CODIGO_ELEMENTO_ORIGEN != null){
          equipment.response.CODIGO_ELEMENTO_ORIGEN = await this._encService.decrypt(equipment.response.CODIGO_ELEMENTO_ORIGEN);
        }

        if(equipment.response.CODIGO_ELEMENTO_DESTINO != null){
          equipment.response.CODIGO_ELEMENTO_DESTINO = await this._encService.decrypt(equipment.response.CODIGO_ELEMENTO_DESTINO);
        }
        
        this.parentEquipmentDetails = equipment.response;
        this.getTotalPendingEquipments();
      }
    }catch(error: any){
      console.log(error);
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado (18).';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado (19).';
      }else{
        this.errorStr = error.error.msg;
      }
      this.hasError = true;
      this.isLoading = false;
    }
  }

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

  navigateArborescence(steps: number){
    let stpesBack = this.arborescence.length - steps;
    if(stpesBack > 0){
      this.goBack(stpesBack);
    }
  }

  async openEquipmentForm(action: string, id: string = '-'){
    this._router.navigate(['sam/GEEQ/REEQ'], {
      queryParams: {
        action: action,
      }
    });
  }

  manageFamilies(){
    this._router.navigate(['sam/GEEQ/DFSU']);
  }

  manageLocations(){
    this._dialog.open(LocationsManagementComponent, {
      width: '520px',
      maxWidth: '520px',
    });
  }

  manageOccupations(){
    this._dialog.open(OccupationManagementComponent, {
      disableClose: true,
      width: '840px',
      maxWidth: '840px',
    })
  }

  async openGraphicArborescence(){
    let arborescenceStr = JSON.stringify(this.graphicArborescence);
    let arborescenceEnc = await this._encService.encrypt(arborescenceStr);

    let dialogRef = this._dialog.open(ArborescenceViewComponent, {
      width: '640px',
      maxWidth: '640px',
      data: {
        arborescence: arborescenceEnc,
      }
    });

    dialogRef.afterClosed().subscribe(res => {
      if(res == 'print'){
        this.printArborescence();
      }
    });
  }

  async printArborescence(){
    try{
      this._resourcesService.openSnackBar('Generando pdf...');

      let arborescenceStr = JSON.stringify(this.graphicArborescence);
      let arborescenceEnc = await this._encService.encrypt(arborescenceStr);
  
      let lastChild = this.arborescence[this.arborescence.length - 1];
      let lastChildArr = lastChild.split(' - ');
      let lastChildEnc = await this._encService.encrypt(lastChildArr[0]);

      let idUser = localStorage.getItem('idusuario')!;
      let fileResponse = await lastValueFrom(this._equipmentManagementService.equipmentGraphicArborescence({
        id_user: idUser,
        linea: 1,
        equipment_code: lastChildEnc,
        equipment_arborescence: arborescenceEnc,
      }));

      if(fileResponse.error){
        this._resourcesService.openSnackBar(fileResponse.msg);
      }else{
        let downloadToken = await lastValueFrom(this._gdelService.getDownloadToken(
          fileResponse.response.fileID,
          idUser,
          1
        ));

        let download = this._document.getElementById('download') as HTMLAnchorElement;
  
        download.href = `http://git.ittec.mx/sam/public/api/download-file/${downloadToken.response.TOKEN}/${idUser}/1`;
        download.download = fileResponse.response.fileID;
        download.click();
      }
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (20).');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (21).');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  manageEquipmentTypes(){
    this._router.navigate(['sam/GEEQ/ADEQ/GCTE']);
  }

  locationsNavigation(){
    this._router.navigate(['sam/GEEQ/ADEQ/LOEQ']);
  }

  navigateToArborescenceCalendar(){
    this._router.navigate(['sam/GEEQ/ADEQ/VAFD']);
  }

  openPendingGroups(action: string){
    let dialogRef = this._dialog.open(GroupPendingComponent, {
      disableClose: true,
      width: '480px',
      maxWidth: '480px',
      data: {
        action: action,
      }
    });

    dialogRef.afterClosed().subscribe(res => {
      if(res != null && res != undefined && res != ''){
        this.changeGroupStatus(res, action);
      }
    })
  }

  private async changeGroupStatus(groupCode: string, action: string){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let formData = new FormData();
      let newStatus = action == 'decline' ? 'Rechazado' : 'Aprobado';
      let codeDec = await this._encService.decrypt(groupCode);

      formData.append('id_user', idUser);
      formData.append('linea', '1');
      formData.append('code', groupCode);
      formData.append('status', newStatus);
      formData.append('comments', 'test aaaaaaaaaaaaaaa');

      await lastValueFrom(this._equipmentManagementService.equipmentPreCodificationGroupStatusUpdate(formData));

      this._resourcesService.openSnackBar(`El grupo de equipos ${codeDec} fue ${newStatus} correctamente.`);
      this.getTotalPendingEquipments();
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (22).');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (23).');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  shouldRefresh(event: any){
    if(event == 'refresh'){
      this.getTotalPendingEquipments();
    }
  }

  familyClicked(event: any){
    this.navigate('family', event);
  }

  private navigate(type: string, code: string){
    if(type == 'family'){
      this._router.navigate(['sam/GEEQ'], {
        queryParams: {
          family: code
        }
      })
    }else if(type == 'subfamily'){
      let currentRoute = window.location.href;
      let routeArr = currentRoute.split('?');
      let family = routeArr.filter(item => item.includes('family'))[0].replace('family=', '');
      family = decodeURIComponent(family);

      this._router.navigate(['sam/GEEQ'], {
        queryParams: {
          family: family,
          subfamily: code
        }
      });
    }else{
      let currentRoute = window.location.href;
      let routeArr = currentRoute.split('?').reverse();
      let paramsArr = routeArr[0].split('&');

      let family = paramsArr.filter(item => item.includes('family'))[0].replace('family=', '');
      family = decodeURIComponent(family);

      let subfamily = paramsArr.filter(item => item.includes('subfamily'))[0].replace('subfamily=', '');
      subfamily = decodeURIComponent(subfamily);

      let arborescenceFilt = paramsArr.filter(item => item.includes('arborescence'));
      let arborescenceArr = [];
      if(arborescenceFilt.length > 0){
        let parentsStr = arborescenceFilt[0].replace('arborescence=', '');
        let parentsDec = window.atob(decodeURIComponent(parentsStr));
        let parentsArr = JSON.parse(parentsDec);

        for(const parent of parentsArr){
          arborescenceArr.push(parent);
        }
      }

      arborescenceArr.push(code);
      let arborescence = window.btoa(JSON.stringify(arborescenceArr));

      this._router.navigate(['sam/GEEQ'], {
        queryParams: {
          family: family,
          subfamily: subfamily,
          arborescence: arborescence
        }
      });
    }
  }

  subfamilyClicked(event: any){
    this.navigate('subfamily', event);
  }

  async updateEquipmentCriticality(event: any){
    try{
      let dataDec = await this._encService.decrypt(event);
      let dataArr = dataDec.split('|');

      if(dataArr.length < 2){
        this._resourcesService.openSnackBar('Los datos seleccionados son inválidos.');
        return;
      }

      let idUser = localStorage.getItem('idusuario')!;
      let formData = new FormData();

      formData.append('id_user', idUser);
      formData.append('linea', '1');
      formData.append('equipment_code', dataArr[1]);
      formData.append('criticality', dataArr[0]);

      await lastValueFrom(this._equipmentManagementService.equipmentUpdateSecurityCriticality(formData));
      this._resourcesService.openSnackBar('La criticidad de seguridad el equipamiento se actualizó correctamente.');
      
      this.isLoading = true;
      this.hasError = false;
      this.errorStr = '';

      this.init(this.params);
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (24).');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (25).');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  async generateFile(event: any){
    try{
      this._resourcesService.openSnackBar('Generando archivo...');

      let dataArr = event.split('|');
      let idUser = localStorage.getItem('idusuario')!;
      let formData = new FormData();

      formData.append('id_user', idUser);
      formData.append('linea', '1');
      formData.append('file_type', dataArr[1]);
      formData.append('file_data', dataArr[0]);

      let response = await lastValueFrom(this._equipmentManagementService.equipmentGenerateEquipmentFile(formData));
      if(response.error){
        this._resourcesService.openSnackBar(response.msg);
      }else{
        let downloadToken = await lastValueFrom(this._gdelService.getDownloadToken(
          response.response.fileID,
          idUser,
          1
        ));

        let download = this._document.getElementById('download') as HTMLAnchorElement;
  
        download.href = `http://git.ittec.mx/sam/public/api/download-file/${downloadToken.response.TOKEN}/${idUser}/1`;
        download.download = response.response.fileID;
        download.click();
      }
    }catch(error: any){
      if(error.error == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado (26).');
      }else if(error.error.msg == undefined){
        this._resourcesService.openSnackBar('Ocurrió un error inesperado .');
      }else{
        this._resourcesService.openSnackBar(error.error.msg);
      }
    }
  }

  openChildren(event: any){
    this.navigate('equipment', event);
  }
}
