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, OnInit } 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';

@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;
  timeLeft = "5:00";

  userName = "";

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

  modulesActivated = false;

  constructor(
    private router: Router,
    private _loginDataService: LoginDataService,
    private _encService: EncService,
    private _socketService: SocketService,
    private _profilesService: UsersProfilesService,
    private dialg: MatDialog,
    private modulesService: ModulesService,
    private _advicesService: AdvicesService,
    private _sysAdminService: SystemAdminService,
    private _resouceService: ResourcesService,
  ) {
    this.navItems = [];
    this.menuItems = [];
  }

  ngOnInit(): void {
    this.onResize();
    this.checkMaintenanceMode();
    let userName = localStorage.getItem('nombre_usuario');

    let profile = localStorage.getItem('perfil');
    let decoder = new TextDecoder('utf-8');
    let encoder = new TextEncoder();

    this._encService.desencriptar(userName!).then(un =>{
      /*this._encService.desencriptar(profile!).then(pr => {
      });*/

      this.userName = un;
    });

    if (window.innerWidth <= 616) {
      this.screen_small = false;
    }else if(window.innerWidth > 616){
      this.screen_small = true;
    }

    this._socketService.refreshPermissions().subscribe(async (profUpdEnc) => {
      let profileUpdated = await this._encService.desencriptar(`${profUpdEnc}`);
      let currentProfile = await this._encService.desencriptar(localStorage.getItem('perfil')!);

      if(profileUpdated == currentProfile){
        try{
          let shortProf = await lastValueFrom(this._encService.shortEncrypt(localStorage.getItem('perfil')!));
          let shortID = await lastValueFrom(this._encService.shortEncrypt(localStorage.getItem('idusuario')!));
          let profInfo: ProfileInterface = await lastValueFrom(this._profilesService.getProfile(
            shortProf.response.encrypted,
            shortID.response.encrypted,
            1
          ));

          let oldPerm = await this._encService.desencriptar(localStorage.getItem('permisos')!);
          let newPerm = JSON.stringify(profInfo.response.PERMISOS);

          if(oldPerm != newPerm){
            let permiEnc = await this._encService.encriptar(newPerm);
            localStorage.setItem('permisos', permiEnc);
          }
        }catch(error: any){
          console.log(error);
        }
      }
    });

    this._socketService.advicePublished().subscribe(async (adviceID) => {
      let idShort = await lastValueFrom(this._encService.shortEncrypt(`${adviceID}`));
      let idEnc = localStorage.getItem('idusuario');
      let shortEnc = await lastValueFrom(this._encService.shortEncrypt(idEnc!));

      let advice: AdviceResponse = await lastValueFrom(this._advicesService.getAdvice(idShort.response.encrypted, shortEnc.response.encrypted, 1));
      let userPublish = await this._encService.desencriptar(advice.response.IDUSUARIO);
      let idDec = await this._encService.desencriptar(idEnc!);

      if(userPublish != idDec){
        let audStr = await this._encService.desencriptar(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.desencriptar(perfEnc!);

        if(profiles.includes(perfDec) || users.includes(idDec)){
          this.openAdviceAlert(advice.response);
        }
      }
    })

    this._socketService.closeSessions().subscribe((data) => {
      this.dialg.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);
    });
  }

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

  async checkMaintenanceMode(){
    try{
      let idUser = localStorage.getItem('idusuario');
      let shortEnc = await lastValueFrom(this._encService.shortEncrypt(idUser!));
      let maintenanceStatus: MaintenanceStatusResponse = await lastValueFrom(this._sysAdminService.getMaintenanceStatus(shortEnc.response.encrypted, 1));

      this.maintenanceMode = maintenanceStatus.response.activated;
      this.getModules();
    }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);
    }
  }

  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.desencriptar(permEnc!);
      let permissions: Permissions = JSON.parse(permDec);

      let idEnc = localStorage.getItem('idusuario');
      let shortEnc = await lastValueFrom(this._encService.shortEncrypt(idEnc!));

      let menu: NestedMenuInterface = await lastValueFrom(this.modulesService.getMenu(shortEnc.response.encrypted, 1));

      this.menuItems = menu.response;
      this.isLoading = false;
    }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}`]);
    /*let moduleInfo = this.menuItems.filter(item => item.IDMODULO == modID)[0];

    let infoObj = {
      route: route,
      module: moduleInfo,
    };

    let infoStr = JSON.stringify(infoObj);
    let infoEnc = await this._encService.encriptar(infoStr);

    this.router.navigate([`sam/module-options`], {
      queryParams: {
        info: infoEnc
      }
    });

    */
  }

  openDialog(msg: string){
    this.dialg.open(AlertComponent, {
      width: '300px',
      data: {
        icon: "error",
        title: '¡Error!',
        description: msg
      }
    });
  }

  // Método de cerrar sesión de manera temporal
  public logoutTemp(){
    localStorage.removeItem('nombre_usuario');
    localStorage.removeItem('idusuario');
    localStorage.removeItem('correo');
    localStorage.removeItem('perfil');
    localStorage.removeItem('token');
    localStorage.removeItem('permisos');
    this.router.navigate(['login']);
    this._resouceService.openSnackBar('Hasta pronto');
  }


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