import { ActivatedRouteSnapshot, CanActivateFn, RouterStateSnapshot } from '@angular/router';
import { inject } from '@angular/core';
import { PermissionsData } from '../components/acquisition-management/acquisition-management.component';
import { ResourcesService } from '../services/resources.service';
import { EncService } from '../services/enc.service';

export const permissionGuard: CanActivateFn = async (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {
  const resourcesService:ResourcesService = inject(ResourcesService);
  const encService:EncService = inject(EncService);
  const arrComponentNotModules: Array<string> = [
    'home', 
    'form-dyn-management', 
    'table-management', 
    'getbfo-create', 
    'forms-management-form',
    'vacation', 
    'initial-data-upload',
    'history-vacation',
    'forms-management',
    'organization',
  ];
  const location: string = state.url;
  const arrLevelsModule: Array<LevelModule> = [
    {id: "ADSI", level: 3}, // Administrador del sistema
    {id: "USPE", level: 4}, // Usuarios y perfiles
    {id: "GEPR", level: 3}, // Gestión de los procesos
    {id: "GDEL", level: 3}, // Gestión documental electrónica
    {id: "GEAD", level: 4}, // Gestión de adquisiciones
    {id: "COAC", level: 3}, // Contadores y activadores
    {id: "GEEQ", level: 3}, // Gestión de los equipamientos
    {id: "GIST", level: 3}, // Gestión de inventario y/o stock
    {id: "GMCO", level: 4}, // Gestión de mantenimiento correctivo
    {id: "GMPR", level: 4}, // Gestión de mantenimiento preventivo
    {id: "GPRS", level: 4}, // Gestión de personal, recursos y subcontratistas
    {id: "GEPR", level: 3}, // Gestión presupuestaria
    {id: "ANFA", level: 3}, // Análisis de fallas
    {id: "PCSA", level: 3}, // Panel de control y seguimiento de actividades
    {id: "IDUE", level: 3}
  ]

  let arrLocation: Array<string> = location.split('/');
  if (arrLocation.length === 0) {
    resourcesService.openSnackBar(`Ocurrió un error al obtener la información de la URL.`);
    return false;
  }
  arrLocation.shift();

  if (arrLocation.length === 1) {
    const app:string = arrLocation[0];
    if (app !== 'sam') {
      resourcesService.openSnackBar(`Ocurrió un error al obtener el dato 'sam`);
      return false;
    }
  }

  if (arrLocation.length === 2) {
    const app:string = arrLocation[0];
    var idModule:string = arrLocation[1];
    if (app !== 'sam') {
      resourcesService.openSnackBar(`Ocurrió un error al obtener el dato 'sam'.`);
      return false;
    }

    if (arrComponentNotModules.includes(idModule)) {
      return true;
    }
    let encPermissions = localStorage.getItem('permisos');
    if (encPermissions === null || encPermissions === undefined || encPermissions === '') {
      resourcesService.openSnackBar(`Ocurrió un error al obtener los permisos del usuario.`);
      return false;
    }
    const strPermissions:string = await encService.decrypt(encPermissions);
    const arrPermissions:Array<PermissionsData> = JSON.parse(strPermissions).permissions;
    
    if(idModule.includes('?')){
      let idModuleArr = idModule.split('?');
      idModule = idModuleArr[0];
    }
    
    if(idModule != 'home'){
      let arrModulePermission = arrPermissions.find((permission:PermissionsData) => permission.id.substring(permission.id.length - 4, permission.id.length) === idModule);
      if (arrModulePermission === null || arrModulePermission === undefined) {
        resourcesService.openSnackBar(`Ocurrió un error al obtener el módulo al que quiere acceder.`);
        return false;
      }
      if (arrModulePermission.access === 0) {
        resourcesService.openSnackBar(`No tienes los permisos necesarios para acceder al módulo.`);
        return false;
      }
    }
  }

  let levelData = arrLevelsModule.find((element: LevelModule) => element.id === arrLocation[1]);
  if (levelData === undefined) {
    return true;
  }

  if (arrLocation.length > 2 && levelData.level === 4) {
    
    const app:string = arrLocation[0];
    const idModule:string = arrLocation[1];
    const idSubmodule:string = arrLocation[2];
    let idFunction:string = '';
    if (3 in arrLocation) {
      idFunction = arrLocation[3];
    }

    if (app !== 'sam') {
      resourcesService.openSnackBar(`Ocurrió un error al obtener el dato 'sam'.`);
      return false;
    }
    
    if (arrComponentNotModules.includes(idModule)) {
      return true;
    }

    let encPermissions = localStorage.getItem('permisos');
    if (encPermissions === null || encPermissions === undefined || encPermissions === '') {
      resourcesService.openSnackBar(`Ocurrió un error al obtener los permisos del usuario.`);
      return false;
    }
    const strPermissions:string = await encService.decrypt(encPermissions);
    const arrPermissions:Array<PermissionsData> = JSON.parse(strPermissions).permissions;    
    
    let arrModulePermission = arrPermissions.find((permission:PermissionsData) => permission.id.substring(permission.id.length - 4, permission.id.length) === idModule);
    if (arrModulePermission === null || arrModulePermission === undefined) {
      resourcesService.openSnackBar(`Ocurrió un error al obtener el módulo al que quiere acceder.`);
      return false;
    }
    if (arrModulePermission.access === 0) {
      resourcesService.openSnackBar(`No tienes los permisos necesarios para acceder al módulo.`);
      return false;
    }
    
    let arrSubmodulePermission = arrModulePermission.children.find((permission:PermissionsData) => permission.id.substring(permission.id.length - 4, permission.id.length) === idSubmodule);
    if (arrSubmodulePermission === null || arrSubmodulePermission === undefined) {
      resourcesService.openSnackBar(`Ocurrió un error al obtener el submódulo al que quiere acceder.`);
      return false;
    }
    if (arrSubmodulePermission.access === 0) {
      resourcesService.openSnackBar(`No tienes los permisos necesarios para acceder al submódulo.`);
      return false;
    }

    if (idFunction !== '') {  
      if(idFunction.includes('?')){
        let idFunctionArr = idFunction.split('?');
        idFunction = idFunctionArr[0];
      }
      
      let arrFunctionPermission = arrSubmodulePermission.children.find((permission:PermissionsData) => permission.id.substring(permission.id.length - 4, permission.id.length) === idFunction);
      if (arrFunctionPermission === null || arrFunctionPermission === undefined) {
        
        resourcesService.openSnackBar(`Ocurrió un error al obtener la función a la que quiere acceder.`);
        return false;
      }
      if (arrFunctionPermission.access === 0) {        
        resourcesService.openSnackBar(`No tienes los permisos necesarios para acceder al esta función.`);
        return false;
      }
    }
  }
  
  return true;
};


export interface LevelModule {
  id:string;
  level: number;
}