import { Component, ElementRef, OnInit } from '@angular/core';
import { ModulesService } from '../../services/modules.service';
import { ActivatedRoute, Router } from '@angular/router';
import { EncService } from '../../services/enc.service';
import { ControlPanelDetails, ControlPanelDetailsResponse, PanelCountersListItem, PanelCountersListResponse, PanelElements } from '../../interfaces/control-panel.interface';
import { UserResponse, UsersResponse } from '../../interfaces/users.interface';
import { MatDialog } from '@angular/material/dialog';
import { LoginDataService } from '../../services/login-data.service';
import { SystemAdminService } from '../../services/system-admin.service';
import { ControlPanelService } from '../../services/control-panel.service';
import { UsersProfilesService } from '../../services/users-profiles.service';
import { SocketService } from '../../services/socket.service';
import { ResourcesService } from '../../services/resources.service';
import { ModulesInterface } from '../../interfaces/modules.interface';
import { lastValueFrom } from 'rxjs';
import { DetailsAlertComponent } from '../system-admin/maintenance-mode/details-alert/details-alert.component';
import { BasicAlertComponent } from '../resources/dialogs/basic-alert/basic-alert.component';

@Component({
    selector: 'app-home',
    templateUrl: './home.component.html',
    styleUrl: './home.component.css',
    standalone: false
})
export class HomeComponent implements OnInit {
  isLoading: boolean;
  hasError: boolean;
  maintenanceEnabled: boolean;
  errorStr: string;
  modules: string[];
  modulesIDS: string[];
  images: string[];
  username: string;
  modulesEnabled: string[];
  hasControlPanel: boolean;
  controlPanel: ControlPanelDetails | null;
  panelElements: PanelElements[];
  users: UserResponse[];
  countersIndicators: PanelCountersListItem[];

  globalData: any;

  constructor(
    private _modulesService: ModulesService, 
    private _router: Router,
    private _el: ElementRef,
    private _encService: EncService,
    private _activatedRoute: ActivatedRoute,
    private _dialog: MatDialog,
    private _loginDataService: LoginDataService,
    private _sysAdminService: SystemAdminService,
    private _controlPanelService: ControlPanelService,
    private _usersProfilesService: UsersProfilesService,
    private _socketService: SocketService,
    private _resourcesService: ResourcesService,
  ) {
    this.isLoading = true;
    this.hasError = false;
    this.maintenanceEnabled = false;
    this.errorStr = "";
    this.modules = [];
    this.images = [];
    this.modulesIDS = [];
    this.username = "";
    this.modulesEnabled = [];
    this.hasControlPanel = false;
    this.controlPanel = null;
    this.panelElements = [];
    this.users = [];
    this.countersIndicators = [];
  }

  ngOnInit(): void {
    this._activatedRoute.queryParams.subscribe(params => {
      let data = params['data'];

      this.globalData = data;
      this.initControlPanel(data);
    });

    this._socketService.panelAssociationsChanged().subscribe(async (msg: any) => {
      let dataEnc = `${msg}`;
      let dataDec = await this._encService.decrypt(dataEnc);
      let dataArr = dataDec.split('|');

      if(dataArr.length == 2){
        let associationsArrEnc = JSON.parse(dataArr[0]);
        let associationsArrDec: string[] = [];
        for(const user of associationsArrEnc){
          let userDec = await this._encService.decrypt(user);
          associationsArrDec.push(userDec);
        }

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

        if(idCurrentPanel == null && associationsArrDec.includes(idUserDec)){
          this.isLoading = true;
          this.hasError = false;
          this.errorStr = '';
          
          this.controlPanel = null;
          this.panelElements = [];
          this.users = [];
          this.countersIndicators = [];

          localStorage.setItem('panel', dataArr[1]);

          this.initControlPanel(this.globalData);
          this._resourcesService.openSnackBar('Su panel de control se actualizó.');
        }else{
          let idCurrentPanelDec = await this._encService.decrypt(idCurrentPanel!);
          let idPanelDec = await this._encService.decrypt(dataArr[1]);

          if(idCurrentPanelDec == idPanelDec && !associationsArrDec.includes(idUserDec)){
            this.controlPanel = null;
            this.panelElements = [];
            this.users = [];
            this.countersIndicators = [];
            this.hasControlPanel = false;
            
            this._resourcesService.openSnackBar('Su panel de control se actualizó.');
          }else if(idCurrentPanelDec != idPanelDec && associationsArrDec.includes(idUserDec)){
            this.isLoading = true;
            this.hasError = false;
            this.errorStr = '';
          
            this.controlPanel = null;
            this.panelElements = [];
            this.users = [];
            this.countersIndicators = [];
  
            localStorage.setItem('panel', dataArr[1]);
  
            this.initControlPanel(this.globalData);
            this._resourcesService.openSnackBar('Su panel de control se actualizó.');
          }
        }
      }
    });
  }

  async initControlPanel(data: any){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let idPanel = localStorage.getItem('panel');

      if(idPanel == null || idPanel == undefined){
        this.hasControlPanel = false;

        if(data == undefined || data == null || data == ""){
          this.getModules();
        }else{
          this.decInfo(data);
        }
      }else{
        let controlPanel: ControlPanelDetailsResponse = await lastValueFrom(this._controlPanelService.getPanel(idPanel, idUser, 1));
        
        this.hasControlPanel = true;
        this.hasError = controlPanel.error;
        this.errorStr = controlPanel.msg;

        if(this.hasError){
          this.isLoading = false;
          return;
        }

        this.controlPanel = controlPanel.response;
        let panelElements: PanelElements[] = JSON.parse(controlPanel.response.INDICADORES_RELACIONADOS);
        for(const element of panelElements){
          element.module = await this._encService.decrypt(element.module);
          element.idElement = await this._encService.decrypt(element.idElement);

          this.panelElements.push(element);
        }

        this.getUsers(data);
      }
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado (1).';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado (2).';
      }else{
        this.errorStr = error.error.msg;
      }

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

  async getModules(){
    try{
      let name = localStorage.getItem('nombre_usuario');
      let nameDec = await this._encService.decrypt(name!);
      this.username = nameDec;

      let permEnc = localStorage.getItem('permisos');
      let permDec = await this._encService.decrypt(permEnc!);
      let permissions: Permissions = JSON.parse(permDec);
      
      let idEnc = localStorage.getItem('idusuario')!;
      let modules: ModulesInterface = await lastValueFrom(this._modulesService.getModules(idEnc, 1));

      if(modules.error){
        this.hasError = true;
        this.isLoading = false;
        this.errorStr = modules.msg;
      }else{
        modules.response.forEach(async (module) => {
          if(this.modulesEnabled.includes(module.ID_MODULO)){
            this.modules.push(module.NOMBRE_MODULO);
            this.modulesIDS.push(module.ID_MODULO);
          }
        });
        this.isLoading = false;
      }
    }catch(error: any){
      this.isLoading = false;
      this.hasError = true;

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

  async decInfo(data: string){
    let dataDec = await this._encService.decrypt(data);
    let dataArr = JSON.parse(dataDec);

    this.maintenanceEnabled = dataArr['maintenance'] == 'enabled';
    this.getModules();
  }

  async getUsers(data: any){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let users: UsersResponse = await lastValueFrom(this._usersProfilesService.getUsers(idUser, 1));

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

      if(this.hasError){
        this.isLoading = false;
      }else{
        let idUserDec = await this._encService.decrypt(idUser);
        let usersArr: UserResponse[] = [];
        for(const user of users.response){
          user.IDUSUARIO = await this._encService.decrypt(user.IDUSUARIO);
          if(user.ESTATUS == 'Activo' && user.IDUSUARIO != idUserDec){
            usersArr.push(user);
          }
        }

        this.users = usersArr;
        this.getIndicators(data);
      }
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado (5).';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado (6).';
      }else{
        this.errorStr = error.error.msg;
      }
    }
  }

  async getIndicators(data: any){
    try{
      let idUser = localStorage.getItem('idusuario')!;
      let indicators: PanelCountersListResponse = await lastValueFrom(this._controlPanelService.getCountersList(idUser, 1));

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

      if(this.hasError){
        this.isLoading = false;
      }else{
        let countersArr: PanelCountersListItem[] = [];
        for(const counter of indicators.response){
          let idCounterDec = await this._encService.decrypt(counter.ID_CONTADOR);
          counter.ID_CONTADOR = idCounterDec;

          countersArr.push(counter);
        }

        this.countersIndicators = countersArr;

        if(data == undefined || data == null || data == ""){
          this.getModules();
        }else{
          this.decInfo(data);
        }
      }
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado (7).';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado (8).';
      }else{
        this.errorStr = error.error.msg;
      }

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

  deactivateMaintenance(){
    let title = "Justificación de la desactivación";
    let body = "Por favor ingrese la justificación de la solución para la desactivación";

    let dialogRef = this._dialog.open(DetailsAlertComponent, {
      data: {
        title: title,
        body: body,
      },
      disableClose: true,
    });

    dialogRef.afterClosed().subscribe(result => {
      if(result != false){
        this.confirmChange(result);
      }
    });
  }

  confirmChange(msg: string){
    let dialogRef = this._dialog.open(BasicAlertComponent, {
      data: {
        title: 'Modo mantenimiento desactivado',
        body: 'El modo mantenimiento ha sido desactivado, deberá iniciar sesión nuevamente al cerrar este cuadro de diálogo.'
      }
    });

    dialogRef.afterClosed().subscribe(async (res) => {
      let idUser = localStorage.getItem('idusuario');
      let formData = new FormData();
      
      formData.append('id_user', idUser!);
      formData.append('linea', '1');
      formData.append('justificacion', msg);
      
      await lastValueFrom(this._sysAdminService.deactivateMaintenanceMode(formData));
      this._loginDataService.logout();
    });
  }
}
