import { MatSnackBar } from '@angular/material/snack-bar';
import { UserConsultResponse } from './../../interfaces/user.interface';
import { MyProfileComponent } from './my-profile/my-profile.component';
import { MaintenanceStatusResponse } from './../../interfaces/maintenance-status.interface';
import { SystemAdminService } from './../../services/system-admin.service';
import { BasicAlertComponent } from './../resources/dialogs/basic-alert/basic-alert.component';
import { AdviceAlertComponent } from './advice-alert/advice-alert.component';
import { Advice, AdviceResponse } from './../../interfaces/advice.interface';
import { AdvicesService } from './../../services/advices.service';
import { NavItem } from './../../interfaces/nav-item.interface';
import { NestedMenuInterface, MenuModules } from './../../interfaces/nested-menu.interface';
import { lastValueFrom } from 'rxjs';
import { UsersProfilesService } from './../../services/users-profiles.service';
import { SocketService } from './../../services/socket.service';
import { EncService } from './../../services/enc/enc.service';
import { Component, Inject, OnInit, ViewChild } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { Router } from '@angular/router';
import { LoginDataService } from 'src/app/services/login/login-data.service';
import { ProfileInterface } from 'src/app/interfaces/profile.interface';
import { Permissions } from './../../interfaces/permissions.interface';
import { AlertComponent } from '../resources/dialogs/alert/alert.component';
import { ModulesService } from 'src/app/services/modules.service';
import { ResourcesService } from 'src/app/services/resources/resources.service';
import { CataloguesService } from 'src/app/services/catalogues.service';
import { HttpErrorResponse } from '@angular/common/http';
import { 
  CatalogueCoins, 
  CatalogueCoinsDocument, 
  CataloguePaymentMethod, 
  CataloguePaymentMethodDocument, 
  ResponseDataCatalogueCoins, 
  ResponseDataCataloguePaymentMethod 
} from 'src/app/interfaces/catalogue.interface';
import { PermissionsData } from '../acquisition-management/acquisition-management.component';
import { TypeForm } from 'src/app/interfaces/acquisition-management/provider.interface';
import { TypeFormSubcontract } from 'src/app/interfaces/personal-managment/subcontractist.interface';
import { EquipmentManagementService } from 'src/app/services/equipment-management.service';
import { EquipmentDetailsResponse } from 'src/app/interfaces/equipment-management.interface';
import { EquipmentAlertComponent } from './equipment-alert/equipment-alert.component';
import { NotificationDetailsResponse, NotificationsListItem, NotificationsListResponse } from 'src/app/interfaces/notification.interface';
import { DOCUMENT } from '@angular/common';
import { NotificationsService } from 'src/app/services/notifications.service';
import { FunctionsService } from 'src/app/services/functions.service';
import { NotificationDialogComponent } from './notification-dialog/notification-dialog.component';
import { MatSidenav } from '@angular/material/sidenav';
import { CorrectiveMaintenanceService } from 'src/app/services/corrective-maintenance.service';

@Component({
  selector: 'app-template',
  templateUrl: './template.component.html',
  styleUrls: ['./template.component.css']
})
export class TemplateComponent implements OnInit {
  nestedMenu: MenuModules[];
  navItems: NavItem[];
  menuItems: MenuModules[];

  showFiller = false;
  panelOpenState = false;
  public screen_small = false;

  maintenanceActivated = false;
  maintenanceMode = false;
  isLoading = true;
  minutesLeft = 5;
  secondsLeft = 0;
  errorsCont = 0;
  timeLeft = "5:00";

  userName = "";

  public title:string = 'Sistema de Ayuda al Manteniemiento L1';

  modulesActivated = false;
  notificationsForPanel: NotificationsListItem[];
  unreadNotifications: number;
  totalNotifications: NotificationsListItem[];

  @ViewChild('rightDrawer') sidenav?: MatSidenav;

  constructor(
    @Inject(DOCUMENT) private _document: Document,
    public resourcesService: ResourcesService,
    private _router: Router,
    private _loginDataService: LoginDataService,
    private _encService: EncService,
    private _socketService: SocketService,
    private _profilesService: UsersProfilesService,
    private _dialog: MatDialog,
    private _modulesService: ModulesService,
    private _advicesService: AdvicesService,
    private _sysAdminService: SystemAdminService,
    private _snackBar: MatSnackBar,
    private _cataloguesService: CataloguesService,
    private _equipmentManagementService: EquipmentManagementService,
    private _notificationsService: NotificationsService,
    private _functionsService: FunctionsService,
    private _correctiveMaintenanceService: CorrectiveMaintenanceService,
  ) {
    this.navItems = [];
    this.menuItems = [];
    this.nestedMenu = [];
    this.notificationsForPanel = [];
    this.unreadNotifications = 0;
    this.totalNotifications = [];
  }

  async ngOnInit() {
    this.isLoading = true;
    await this.init();
    await this.checkCatalogues();

    this.isLoading = false;

  }

  async init(){
    try{
      //Ejecutar el tamaño de la pantalla inicial
      this.onResize();
      //Consultar el estado del modo mantenimiento
      let idUser = localStorage.getItem('idusuario');
      let maintenanceStatus: MaintenanceStatusResponse = await lastValueFrom(this._sysAdminService.getMaintenanceStatus(idUser!, 1));

      this.maintenanceMode = maintenanceStatus.response.activated;
      
      //Obtención del menú de módulos, submódulos, funciones y pantallas del SAM
      let menu: NestedMenuInterface = await lastValueFrom(this._modulesService.getMenu(idUser!, 1));
      //Lectura, decodificación y procesamiento de los permisos del usuario
      let permissions = localStorage.getItem('permisos');
      let permStr = await this._encService.decrypt(permissions!);
      let permObj: Permissions = JSON.parse(permStr);
      menu.response.forEach(item => {
        let idMod = item.IDMODULO;
        let modPerm = permObj.permissions.filter(item2 => item2.id == idMod)[0];
        let access = modPerm.access;
        if(access > 0){
          this.menuItems.push(item);
        }
      });
      
      //Conexiones a los eventos del Socket
      if (window.innerWidth <= 616) {
        this.screen_small = false;
      }else if(window.innerWidth > 616){
        this.screen_small = true;
      }
  
      this._socketService.refreshPermissions().subscribe(async (profUpdEnc) => {
        let idUser = localStorage.getItem('idusuario')!;
        let usrInfo: UserConsultResponse = await lastValueFrom(this._profilesService.getUser(idUser, idUser, 1));
        let currentProfile = await this._encService.decrypt(localStorage.getItem('perfil')!);

        if(parseInt(currentProfile) != usrInfo.response.PERFIL){
          let perfEnc = await this._encService.encrypt(`${usrInfo.response.PERFIL}`);
          localStorage.setItem('perfil', perfEnc);
          currentProfile = `${usrInfo.response.PERFIL}`;
        }

        let profileUpdated = await this._encService.decrypt(`${profUpdEnc}`);
  
        if(profileUpdated == currentProfile){
          try{
            let profile = localStorage.getItem('perfil')!;
            let profInfo: ProfileInterface = await lastValueFrom(this._profilesService.getProfile(
              profile,
              idUser,
              1
            ));
  
            let oldPerm = await this._encService.decrypt(localStorage.getItem('permisos')!);
            let newPerm = JSON.stringify(profInfo.response.PERMISOS);
  
            if(oldPerm != newPerm){
              let permiEnc = await this._encService.encrypt(newPerm);
              localStorage.setItem('permisos', permiEnc);
              this.menuItems = [];

              this.nestedMenu.forEach(item => {
                let idMod = item.IDMODULO;
                let modPerm = profInfo.response.PERMISOS.permissions.filter(item2 => item2.id == idMod)[0];
                let access = modPerm.access;
                if(access > 0){
                  this.menuItems.push(item);
                }
              });

              this.openSnackBar('Sus permisos fueron actualizados.');
            }
          }catch(error: any){
            if(error.error == undefined){
              this.openDialog('Ocurrió un error al actualizar su perfil');
            }else if(error.error.msg == undefined){
              this.openDialog('Ocurrió un error al actualizar su perfil');
            }else{
              this.openDialog(error.error.msg);
            }
          }
        }
      });
  
      this._socketService.advicePublished().subscribe(async (adviceID) => {
        console.log(adviceID);
        
        let idEnc = localStorage.getItem('idusuario')!;
  
        let advice: AdviceResponse = await lastValueFrom(this._advicesService.getAdvice(`${adviceID}`, idEnc, 1));
        let userPublish = await this._encService.decrypt(advice.response.IDUSUARIO);
        let idDec = await this._encService.decrypt(idEnc!);
  
        if(userPublish != idDec){
          let audStr = await this._encService.decrypt(advice.response.AUDIENCIA);
          let audArr = JSON.parse(audStr);
  
          let profiles: string[] = [];
          let users: string[] = [];
  
          audArr.forEach((item: any) => {
            let itemArr = item.split('-');
  
            if(itemArr[0] == 'prof'){
              profiles.push(itemArr[1]);
            }else{
              users.push(itemArr[1]);
            }
          });
  
          let perfEnc = localStorage.getItem('perfil');
          let perfDec = await this._encService.decrypt(perfEnc!);
  
          if(profiles.includes(perfDec) || users.includes(idDec)){
            this.openAdviceAlert(advice.response);
          }
        }
      })
  
      this._socketService.closeSessions().subscribe((data) => {
        this._dialog.open(BasicAlertComponent, {
          data: {
            title: 'Modo mantenimiento activado',
            body: 'El modo mantenimiento fue activado por un administrador, el sistema entrará en este modo en 5 minutos, por lo tanto deberá guardar sus cambios y cerrar sesión antes de terminar el tiempo.'
          }
        });
  
        this.maintenanceActivated = true;
  
        let interval = setInterval(() => {
          if(this.secondsLeft == 0 && this.minutesLeft > 0){
            this.minutesLeft--;
            this.secondsLeft = 59;
          }else if(this.secondsLeft > 0 && this.minutesLeft >= 0){
            this.secondsLeft--;
          }else{
            clearInterval(interval);
            this.logout();
          }
  
          let secondsStr = this.secondsLeft > 9 ? `${this.secondsLeft}` : `0${this.secondsLeft}`;
          this.timeLeft = `${this.minutesLeft}:${secondsStr}`;
        }, 1000);
      });

      this._socketService.getNewProvider().subscribe(async (idProvider) => {
        if (idProvider === null || idProvider === undefined || idProvider === '') {
          this.resourcesService.openSnackBar(`Ocurrió un error al obtener el ID del provedor.`);
          return; 
        }

        const encPermisos = localStorage.getItem('permisos');
        if (encPermisos === undefined || encPermisos === null || encPermisos === '') {
          return ;
        }
        const strPermisos:string = await this._encService.decrypt(encPermisos);
        const arrPermisos = JSON.parse(strPermisos);

        arrPermisos.permissions.map(async (permissionModule:PermissionsData) => {
          if (permissionModule.id === 'S002V01M11GPRS' && permissionModule.access > 0) {

            permissionModule.children.map(async (permissionSubmodule:PermissionsData) => {
              if (permissionSubmodule.id === 'S002V01S01GESU' && permissionSubmodule.access > 0) {

                permissionSubmodule.children.map(async (permissionFunction:PermissionsData) => {
                  if (permissionFunction.id === 'S002V01F01GESU' && permissionFunction.access > 0) {

                    permissionFunction.children.map(async (permissionPantalla:PermissionsData) => {
                      if (permissionPantalla.id === 'S002V01P02RESU' && permissionPantalla.access === 2) {
                        this._dialog.open(AlertComponent, {
                          width: '500px',
                          data: {
                            icon: 'warning',
                            title: `Registro Nuevo`,
                            description: `Se ha registrado un nuevo proveedor en el Módulo de Adquisiciones ¿Desea registrar el proveedor como un subcontratista en este momento?`
                          }
                        }).afterClosed().subscribe(async (result) => {
                          if (result) {
                            
                            const typeFormSubcontract: TypeFormSubcontract = {
                              type: 'REG',
                              idSubcontract: null,
                              idProvider: `${idProvider.toString()}`,
                            }
                      
                            const strFormSubcontract:string = JSON.stringify(typeFormSubcontract);
                            const encFormSubcontract: string = await this._encService.encrypt(strFormSubcontract);

                            this._router.navigate([`/sam/GPRS/GESU/GESU/subcontratist/form/${encFormSubcontract}`]);
                          }
                        });
                      }
                    });
                  }
                });
              }
            });
          }
        });
      });

      this._socketService.getNotice().subscribe(async (msg) => {

        if (msg === null || msg === undefined || msg === '') {
          this.resourcesService.openSnackBar(`Ocurrió un error al obtener el mensaje.`);
          return; 
        }

        const encPermisos = localStorage.getItem('permisos');
        if (encPermisos === undefined || encPermisos === null || encPermisos === '') {
          return ;
        }
        const strPermisos:string = await this._encService.decrypt(encPermisos);
        const arrPermisos = JSON.parse(strPermisos);
        arrPermisos.permissions.map(async (permissionModule:PermissionsData) => {
          if (permissionModule.id === 'S002V01M11GPRS' && permissionModule.access > 0) {

            permissionModule.children.map(async (permissionSubmodule:PermissionsData) => {
              if (permissionSubmodule.id === 'S002V01S01GESU' && permissionSubmodule.access > 0) {

                permissionSubmodule.children.map(async (permissionFunction:PermissionsData) => {
                  if (permissionFunction.id === 'S002V01F01GESU' && permissionFunction.access > 0) {

                    permissionFunction.children.map(async (permissionPantalla:PermissionsData) => {
                      if (permissionPantalla.id === 'S002V01P02RESU' && permissionPantalla.access === 2) {
                        this.resourcesService.openSnackBar(`${msg}`);
                      }
                    });
                  }
                });
              }
            });
          }
        });

        
      });

      this._socketService.getNewSubcontract().subscribe(async (idSubcontract) => {
        console.log(idSubcontract);
        
        if (idSubcontract === null || idSubcontract === undefined || idSubcontract === '') {
          this.resourcesService.openSnackBar(`Ocurrió un error al obtener el ID del provedor.`);
          return; 
        }

        const encPermisos = localStorage.getItem('permisos');
        if (encPermisos === undefined || encPermisos === null || encPermisos === '') {
          return ;
        }
        const strPermisos:string = await this._encService.decrypt(encPermisos);
        const arrPermisos = JSON.parse(strPermisos);

        arrPermisos.permissions.map(async (permissionModule:PermissionsData) => {
          if (permissionModule.id === 'S002V01M05GEAD' && permissionModule.access > 0) {

            permissionModule.children.map(async (permissionSubmodule:PermissionsData) => {
              if (permissionSubmodule.id === 'S002V02S02PROV' && permissionSubmodule.access > 0) {

                this._dialog.open(AlertComponent, {
                  width: '500px',
                  data: {
                    icon: 'warning',
                    title: `Registro Nuevo`,
                    description: `Se ha registrado un nuevo subcontratista en el Módulo de Gestión de personal, recursos y subcontratistas ¿Desea registrar el subcontratista como un proveedor en este momento?`
                  }
                }).afterClosed().subscribe(async (result) => {
                  if (result) {
                    let typeForm: TypeForm = { type: 'REGI', subcontract: `${idSubcontract.toString()}` }
                    let strTypeForm: string = JSON.stringify(typeForm);
                    let encTypeForm: string = await this._encService.encrypt(strTypeForm);
                   
                    this._router.navigate([`/sam/GEAD/PROV/ESWP/${encTypeForm}`]);
                  }
                });

                
              }
            });
          }
        });
      });

      this._socketService.equipmentAlert().subscribe(async (alertData) => {
        try{
          let permissionsStr = localStorage.getItem('permisos')!;
          let permissionsDec = await this._encService.decrypt(permissionsStr);
          let permissionsObj = JSON.parse(permissionsDec);
          let correctiveMaintenanceEnabled = false;

          for(const permission of permissionsObj.permissions){
            if(permission.id == 'S002V01M09GMCO'){
              correctiveMaintenanceEnabled = permission.access > 0;
            }
          }

          if(correctiveMaintenanceEnabled){
            let idUser = localStorage.getItem('idusuario')!;
            let equipment: EquipmentDetailsResponse = await lastValueFrom(this._equipmentManagementService.equipmentConsultOnly(
              alertData.equipment,
              idUser,
              1
            ));
            
            let codeDec = await this._encService.decrypt(equipment.response.CODIGO);
            let tipoDec = await this._encService.decrypt(equipment.response.TIPO_EQUIPAMIENTO);
            let modeloDec = await this._encService.decrypt(equipment.response.MODELO);
            let idDec = await this._encService.decrypt(equipment.response.ID_EQUIPAMIENTO);

            let label = `Se ha detectado una medición que ha generado una órden de mantenimiento correctivo para el equipamiento`;
            let dialogRef = this._dialog.open(EquipmentAlertComponent, {
              width: '520px',
              disableClose: true,
              data: {
                equipmentCode: `${codeDec} - ${tipoDec} - ${modeloDec} (${idDec})`,
                label: label,
              }
            });

            dialogRef.afterClosed().subscribe(res => {
              console.log(res);
            })
          }
        }catch(error: any){
          console.log(error);
          if(error.error == undefined){
            this.resourcesService.openSnackBar('Ocurrió un error inesperado.');
          }else if(error.error.msg == undefined){
            this.resourcesService.openSnackBar('Ocurrió un error inesperado.');
          }else{
            this.resourcesService.openSnackBar(error.error.msg);
          }
        }
      });

      this._socketService.notificationPublished().subscribe(async (notificationData) => {
        try{
          let audienceStr = await this._encService.decrypt(notificationData.audience);
          let audienceArr = JSON.parse(audienceStr);

          let idUser = localStorage.getItem('idusuario')!;
          let idUserDec = await this._encService.decrypt(idUser);

          if(audienceArr.includes(idUserDec)){
            let notification: NotificationDetailsResponse = await lastValueFrom(this._notificationsService.getNotification(
              notificationData.idNotification,
              'N',
              idUser, 
              1
            ));

            if(notification.error){
              this.resourcesService.openSnackBar(notification.msg);
            }else{
              notification.response.FECHA = this._functionsService.getDateTimeHour(notification.response.FECREG);
              notification.response.FECREG_DISP = this._functionsService.notificationDate(notification.response.FECREG);
  
              let audienceArr = JSON.parse(notification.response.AUDIENCIA);
              for(const user of audienceArr as string[]){
                let userDec = await this._encService.decrypt(user);
                if(userDec == idUserDec){
                  let notificationsAux = this.totalNotifications;
                  notificationsAux.reverse();
                  notificationsAux.push(notification.response);
                  notificationsAux.reverse();
  
                  this.totalNotifications = notificationsAux;
                  this.notificationsForPanel.push(notification.response);
                  this.unreadNotifications++;
      
                  setTimeout(() => {
                    let divNotification = this._document.getElementById(`notification-${notification.response.ID_NOTIFICACION}`);
                    //Eliminar la clase de entrada
                    divNotification?.classList.remove('push-notification-enter');
                    //Añadir la clase de salida
                    divNotification?.classList.add('push-notification-out');
                    //Se elimina la notificación del arreglo después de esperar la animación
                    setTimeout(() => {
                      let notificationsAux: NotificationsListItem[] = [];
                      for(const notificationObj of this.notificationsForPanel){
                        if(notificationObj.ID_NOTIFICACION != notification.response.ID_NOTIFICACION){
                          notificationsAux.push(notificationObj);
                        }
                      }
                
                      this.notificationsForPanel = notificationsAux;
                    }, 800);
                  }, 5000);
                }
              }
            }
          }
        }catch(error: any){
          if(error.error == undefined){
            this.resourcesService.openSnackBar('Ocurrió un error inesperado.');
          }else if(error.error.msg == undefined){
            this.resourcesService.openSnackBar('Ocurrió un error inesperado.');
          }else{
            this.resourcesService.openSnackBar(error.error.msg);
          }
        }
      });

      let userName = localStorage.getItem('nombre_usuario');
      let name = await this._encService.decrypt(userName!);

      await this.getNotifications();
      
      this.userName = name;
      this.nestedMenu = menu.response;
      
      this.isLoading = false;
      this.checkCatalogues();

      setInterval(() => {
        let notificationsAux: NotificationsListItem[] = [];
        for(const notification of this.totalNotifications){
          notification.FECREG_DISP = this._functionsService.notificationDate(notification.FECREG);
          notificationsAux.push(notification);
        } 

        this.totalNotifications = notificationsAux;
      }, 30000);
    }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.errorsCont++;
      this.openDialog(msg);
    }
  }

  async getNotifications(){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let notifications: NotificationsListResponse = await lastValueFrom(this._notificationsService.getNotificationsByUser(idUser, 1));

      if(notifications.error){
        this.openDialog(notifications.msg);
      }else{
        let notificationsArr: NotificationsListItem[] = [];
        let idUserDec = await this._encService.decrypt(idUser);

        for(const notification of notifications.response){
          let scopeArr = JSON.parse(notification.ALCANCE);
          for(const item of scopeArr){
            let userDec = await this._encService.decrypt(item.USUARIO);
            if(userDec == idUserDec && item.ESTADO == 'No leído'){
              this.unreadNotifications++;
              notification.READED = false;
            }else if(userDec == idUserDec && item.ESTADO == 'Leído'){
              notification.READED = true;
            }
          }
          
          notification.FECREG_DISP = this._functionsService.notificationDate(notification.FECREG)!;
          notificationsArr.push(notification);
        }

        this.totalNotifications = notificationsArr;
      }
    }catch(error: any){
      if(error.error == undefined){
        this.openDialog('Ocurrió un error inesperado.');
      }else if(error.error.msg == undefined){
        this.openDialog('Ocurrió un error inesperado.');
      }else{
        this.openDialog(error.error.msg);
      }
    }
  }

  closeNotification(id: string){
    let notification = this._document.getElementById(`notification-${id}`);
    //Eliminar la clase de entrada
    notification?.classList.remove('push-notification-enter');
    //Añadir la clase de salida
    notification?.classList.add('push-notification-out');
    //Se elimina la notificación del arreglo después de esperar la animación
    setTimeout(() => {
      let notificationsAux: NotificationsListItem[] = [];
      for(const notificationObj of this.notificationsForPanel){
        if(notificationObj.ID_NOTIFICACION != id){
          notificationsAux.push(notificationObj);
        }
      }

      this.notificationsForPanel = notificationsAux;
    }, 800);
  }

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

  openDialog(msg: string){
    let msgFin = this.errorsCont < 3 ? msg : 'El error persiste, por favor contacte al departamenteo de TI para solucionarlo.';
    let _dialogRef = this._dialog.open(AlertComponent, {
      width: '300px',
      data: {
        icon: "error",
        title: '¡Error!',
        description: msgFin
      }
    });

    _dialogRef.afterClosed().subscribe((_) => {
      if(this.errorsCont < 3){
        location.reload();
      }else{
        this.logout();
      }
    })
  }

  openAdviceAlert(advice: Advice){
    this._dialog.open(AdviceAlertComponent, {
      data: advice
    });
  }

  openViewProfilesAdmin() {
    this._router.navigate([
      'sam/users-profiles'
    ]);
  }

  openViewUsersAdmin() {
    this._router.navigate([
      'sam/new-user'
    ]);
  }

  logout () {
    this._loginDataService.logout()
  }

  async getModules(){
    try{
      let permEnc = localStorage.getItem('permisos');
      let permDec = await this._encService.decrypt(permEnc!);
      let permissions: Permissions = JSON.parse(permDec);

      let idEnc = localStorage.getItem('idusuario')!;
      let menu: NestedMenuInterface = await lastValueFrom(this._modulesService.getMenu(idEnc, 1));

      this.menuItems = menu.response;
    }catch(error: any){
      let errorStr = "";

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

      this.openDialog(errorStr);
    }
  }

  async navigate(modID: string){
    let route = modID.substring(10, modID.length);
    this.modulesActivated = false;
    this._router.navigate([`sam/${route}`]);
  }

  public onResize(){
    this.title = window.innerWidth <= 1050 ? 'SAM L1' : 'Sistema de Ayuda al Manteniemiento L1';
  }

  closeNestedMenu(){
    this.modulesActivated = false;
  }

  openMyProfile(){
    this._dialog.open(MyProfileComponent, {
      width: '580px'
    });
  }

  private async checkCatalogues() {
    const encPermisos:string = localStorage.getItem('permisos')!;
    const strPermisos:string = await this._encService.decrypt(encPermisos);
    const arrPermisos = JSON.parse(strPermisos);

    await Promise.all(
      arrPermisos.permissions.map(async (modules:any) => {      
        if (modules.id === 'S002V01M05GEAD' && modules.access > 0) {

          await Promise.all(
            modules.children.map(async (submodule:any) => {
              if (submodule.id === 'S002V02S02PROV' && submodule.access > 0) {

                await Promise.all(
                  submodule.children.map(async (functions:any) => {
                    if (functions.id === 'S002V01F05GVPA' && functions.access == 2) {
                      let catalogCoins = localStorage.getItem('catalogo_moneda');                
                      if (catalogCoins === null) {
                        const idUser:string = this.resourcesService.getUser();
                        const line: number = parseInt(this.resourcesService.getLineNumber());
                        await lastValueFrom(this._cataloguesService.getGeneralCatalogueInfo('c_Moneda', 5, idUser, line)).then(
                          async (responseData:ResponseDataCatalogueCoins) => {
                            if (!responseData.error) {    
                              let arrCataloguesCoinsDocument:Array<CatalogueCoinsDocument> = responseData.response;
                              let arrCataloguesCoins:Array<CatalogueCoins> = arrCataloguesCoinsDocument.map((cataloguesCoins:CatalogueCoinsDocument) =>  {
                                return {
                                  C_MONEDA: cataloguesCoins.c_Moneda,
                                  DESCRIPCION: cataloguesCoins.Descripción,
                                  DECIMALES: cataloguesCoins.Decimales,
                                  PORCENTAJE_VARIACION: cataloguesCoins.Porcentaje_variación,
                                  FECHA_INICIO_DE_VIGENCIA: cataloguesCoins.Fecha_inicio_de_vigencia,
                                  FECHA_FIN_DE_VIGENCIA: cataloguesCoins.Fecha_fin_de_vigencia,
                                }
                              });
                              arrCataloguesCoins = arrCataloguesCoins.filter((cataloguesCoins:CatalogueCoins) =>  
                                cataloguesCoins.C_MONEDA !== null && cataloguesCoins.DESCRIPCION !== null
                              );
      
                              const strCataloguesCoins:string = JSON.stringify(arrCataloguesCoins);
                              const encCataloguesCoins:string = await this._encService.encrypt(strCataloguesCoins);
                              localStorage.setItem('catalogo_moneda', encCataloguesCoins);
                            } else {
                              this.resourcesService.openSnackBar(`${responseData.msg}`);
                            }
                          }, (httpErrorResponse:HttpErrorResponse) => this.resourcesService.checkErrors(httpErrorResponse)
                        );
                      } 
      
                      let catalogMethodPay = localStorage.getItem('catalogo_metodo_pago');
                      if (catalogMethodPay === null) {
                        const idUser:string = this.resourcesService.getUser();
                        const line: number = parseInt(this.resourcesService.getLineNumber());
                        await lastValueFrom(this._cataloguesService.getGeneralCatalogueInfo('c_FormaPago', 6, idUser, line)).then(
                          async (responseData:ResponseDataCataloguePaymentMethod) => {
                            if (!responseData.error) {                        
                              let arrCataloguesPaymentMethodDocument:Array<CataloguePaymentMethodDocument> = responseData.response;
                              let arrCataloguesPaymentMethod: Array<CataloguePaymentMethod> = arrCataloguesPaymentMethodDocument.map(( cataloguePaymentMethod:CataloguePaymentMethodDocument ) => {
                                return {
                                  C_FORMAPAGO: cataloguePaymentMethod.c_FormaPago,
                                  DESCRIPCION: cataloguePaymentMethod.Descripción,
                                  BANCARIZADO: cataloguePaymentMethod.Bancarizado,
                                  NUMERO_DE_OPERACION: cataloguePaymentMethod.Número_de_operación,
                                  RFC_DEL_EMISOR_DE_LA_CUENTA_ORDENANTE: cataloguePaymentMethod.RFC_del_Emisor_de_la_cuenta_ordenante,
                                  CUENTA_ORDENANTE: cataloguePaymentMethod.Cuenta_Ordenante,
                                  PATRON_PARA_CUENTA_ORDENANTE: cataloguePaymentMethod.Patrón_para_cuenta_ordenante,
                                  RFC_DEL_EMISOR_CUENTA_DE_BENEFICIARIO: cataloguePaymentMethod.RFC_del_Emisor_Cuenta_de_Beneficiario,
                                  CUENTA_DE_BENENFICIARIO: cataloguePaymentMethod.Cuenta_de_Benenficiario,
                                  PATRON_PARA_CUENTA_BENEFICIARIA: cataloguePaymentMethod.Patrón_para_cuenta_Beneficiaria,
                                  TIPO_CADENA_PAGO: cataloguePaymentMethod.Tipo_Cadena_Pago,
                                  NOMBRE_DEL_BANCO_EMISOR_DE_LA_CUENTA_ORDENANTE_EN_CASO_DE_EXTRANJERO: cataloguePaymentMethod.Nombre_del_Banco_emisor_de_la_cuenta_ordenante_en_caso_de_extranjero,
                                  FECHA_INICIO_DE_VIGENCIA: cataloguePaymentMethod.Fecha_inicio_de_vigencia,
                                  FECHA_FIN_DE_VIGENCIA: cataloguePaymentMethod.Fecha_fin_de_vigencia,
                                }
                              });
                              arrCataloguesPaymentMethod = arrCataloguesPaymentMethod.filter((cataloguesMethodPay:CataloguePaymentMethod) => 
                                cataloguesMethodPay.C_FORMAPAGO !== null && cataloguesMethodPay.DESCRIPCION !== null 
                              );
                              localStorage.removeItem
                              const strCataloguesPaymentMethod:string = JSON.stringify(arrCataloguesPaymentMethod);
                              const encCataloguesPaymentMethod:string = await this._encService.encrypt(strCataloguesPaymentMethod);
                              localStorage.setItem('catalogo_metodo_pago', encCataloguesPaymentMethod);
                            } else {
                              this.resourcesService.openSnackBar(`${responseData.msg}`);
                            }
                          }, (httpErrorResponse:HttpErrorResponse) => this.resourcesService.checkErrors(httpErrorResponse)
                        );
                      }  
                    }
                  })
                );

              } 
            })
          );
        } 
      })
    );
  }

  public vacation() {
    
  }

  openNotification(idNotification: string, isFromSidenav: boolean){
    let notificationFilt = this.totalNotifications.filter(item => item.ID_NOTIFICACION == idNotification);
    if(notificationFilt.length > 0){
      let notification = notificationFilt[0];
      notification.READED = true;

      let notificationsAux: NotificationsListItem[] = [];
      for(const notificationObj of this.totalNotifications){
        if(notificationObj.ID_NOTIFICACION == notification.ID_NOTIFICACION){
          notificationsAux.push(notification);
        }else{
          notificationsAux.push(notificationObj);
        }
      }

      this.totalNotifications = notificationsAux;
      this.unreadNotifications--;
    }
    
    this.closeNotification(idNotification);
    let dialogRef = this._dialog.open(NotificationDialogComponent, {
      width: '520px',
      data: {
        idNotification: idNotification,
      }
    });

    dialogRef.afterClosed().subscribe(res => {
      if(res != null && res != undefined && res != ''){
        let resArr = res.split('|');
        if(resArr.length < 2){
          this.resourcesService.openSnackBar('La acción seleccionada es inválida.');
        }else if(resArr[0] == 'go'){
          this.navigateFromNotification(resArr[1]);
        }

      }

      if(isFromSidenav){
        this.sidenav?.close();
      }
    });
  }

  private async navigateFromNotification(routeEnc: string){
    let routeDec = await this._encService.decrypt(routeEnc);
    this._router.navigate([`sam/${routeDec}`]);
  }
}
