import { ActivatedRoute, Router } from '@angular/router';
import { ConnectionsResponse } from './../../../interfaces/connections.interface';
import { MatSnackBar } from '@angular/material/snack-bar';
import { ConnectionsService } from './../../../services/connections.service';
import { SocketService } from './../../../services/socket.service';
import { EncService } from './../../../services/enc/enc.service';
import { UsersProfilesService } from './../../../services/users-profiles.service';
import { lastValueFrom } from 'rxjs';
import { UsersResponse, UserResponse } from './../../../interfaces/users.interface';
import { Component, OnInit } from '@angular/core';
import { Location } from '@angular/common';

@Component({
  selector: 'app-connections',
  templateUrl: './connections.component.html',
  styleUrls: ['./connections.component.css']
})
export class ConnectionsComponent implements OnInit {
  isLoading: boolean;
  hasError: boolean;
  errorStr: string;
  modIcon: string;
  modName: string;
  menuIcon: string;
  menuName: string;

  users: UserResponse[];
  usersConnected: string[];
  usersDisconnected: string[];

  connectedUsers: number;
  disconnectedUsers: number;

  constructor(
    private _usersProfilesSevice: UsersProfilesService, 
    private _encService: EncService,
    private _socketService: SocketService,
    private _connectionsService: ConnectionsService,
    private _snackBar: MatSnackBar,
    private _router: Router,
    private _activeRoute: ActivatedRoute,
    private _location: Location,
  ) { 
    this.isLoading = true;
    this.hasError = false;
    this.errorStr = "";
    this.modIcon = "";
    this.modName = "";
    this.menuIcon = "";
    this.menuName = "";

    this.users = [];
    this.usersConnected = [];
    this.usersDisconnected = [];

    this.connectedUsers = 0;
    this.disconnectedUsers = 0;
  }

  ngOnInit(): void {
    this.getUsers().then(() => {
      this.buildConnections();
      this.initSocketListener();
    });
  }

  async mapData(data: string){
    let infoDec = await this._encService.desencriptar(data);
    let infoObj = JSON.parse(infoDec);

    this.modIcon = infoObj.modIcon;
    this.modName = infoObj.modName;
    this.menuIcon = infoObj.menu.ICONOMENU;
    this.menuName = infoObj.menu.NOMBREMENU;
  }

  async getUsers(){
    try{
      let idEnc = localStorage.getItem('idusuario');
      let idShort = await lastValueFrom(this._encService.shortEncrypt(idEnc!));
      
      let users: UsersResponse = await lastValueFrom(this._usersProfilesSevice.getUsers(idShort.response.encrypted, 1));
      
      this.hasError = users.error;
      if(this.hasError){
        this.isLoading = false;
        this.errorStr = users.msg;
      }else{
        let currentUser = localStorage.getItem('idusuario');
        let decryptedUser = await this._encService.desencriptar(currentUser!);
        let idCurrent = parseInt(decryptedUser);
        
        users.response.forEach(item => {
          let idUser = parseInt(item.IDUSUARIO);
          
          if(idCurrent != idUser){
            this.users.push(item);
          }
        });
        
        this.isLoading = false;
      }
    }catch(error: any){
      this.isLoading = false;
      this.hasError = true;
      this.errorStr = error.error.msg;
    }
  }

  async getConnections(){
    try{
      let connections: ConnectionsResponse = await lastValueFrom(this._connectionsService.getUsersConnections());
      
      connections.response.forEach(element => {
        let userArr = this.users.filter(item => item.IDUSUARIO == element.IDUSUARIO);
        
        if(userArr.length > 0){
          let user = userArr[0];
          let index = this.users.indexOf(user);
          
          let usrSus: UserResponse = {
            IDUSUARIO: user.IDUSUARIO,
            NOMBRE: user.NOMBRE,
            APEPAT: user.APEPAT,
            APEMAT: user.APEMAT,
            EMAIL: user.EMAIL,
            PERFIL: user.PERFIL,
            ESTATUS: user.ESTATUS,
            ULCON: element.ULCON
          }
          
          this.users[index] = usrSus;
        }
      });
    }catch(error: any){
      this.openSnackBar("No se pudieron recuperar las conexiones de los usuarios");
    }
  }

  openSnackBar(error: string){
    this._snackBar.open(error, undefined, {
      duration: 10000
    })
  }

  initSocketListener(){
    let currentId = localStorage.getItem('idusuario');

    this._socketService.currentConnections().subscribe((res) => {
      let resStr = `${res}`;
      let resArr = JSON.parse(resStr);
      this.usersConnected = [];
      this.connectedUsers = 0;
      
      resArr.forEach((item: any) => {
        let itemArr = `${item}`.split('.');
        let id = itemArr[0];

        if(id != currentId){
          this._encService.desencriptar(id).then(idDec => {
            if(!this.usersConnected.includes(idDec)){
              this.usersConnected.push(idDec);
              this.connectedUsers++;
            }
            
            this.buildConnections();
          });
        }
      });
    });

    this._socketService.newConnection().subscribe(res => {
      let resStr = `${res}`;
      let resArr = JSON.parse(resStr);

      this.usersConnected = [];
      this.connectedUsers = 0;

      resArr.forEach((item: any) => {
        let itemArr = `${item}`.split('.');
        let id = itemArr[0];
        
        if(id != currentId){
          this._encService.desencriptar(id).then(idDec => {
            if(!this.usersConnected.includes(idDec)){
              this.usersConnected.push(idDec);
              this.connectedUsers++;
            }
            
            this.buildConnections();
          })
        }
      });
    });

    this._socketService.disconnection().subscribe(res => {
      let resStr = `${res}`;
      let resArr = JSON.parse(resStr);

      this.usersConnected = [];
      this.connectedUsers = 0;

      resArr.forEach((item: any) => {
        let itemArr = `${item}`.split('.');
        let id = itemArr[0];
        
        if(id != currentId){
          this._encService.desencriptar(id).then(idDec => {
            this.usersConnected.push(idDec);
            this.connectedUsers++;

            this.getConnections();
            this.buildConnections();
          })
        }else if(id == currentId && resArr.length == 1){
          this.getConnections();
          this.buildConnections();
        }
      });
    });
    
    this._socketService.getConnections();
  }

  buildConnections(){
    this.usersDisconnected = [];
    this.disconnectedUsers = 0;
    this.users.forEach(item => {
      if(!this.usersConnected.includes(item.IDUSUARIO)){
        this.usersDisconnected.push(item.IDUSUARIO);
        this.disconnectedUsers++;
      }
    });
  }

  getUserName(id: string){
    let usrFil = this.users.filter(user => user.IDUSUARIO == id);
    let usr = usrFil[0];
    
    return `${this.buildName(usr.NOMBRE, usr.APEPAT, usr.APEMAT)} (${id})`;
  }

  getLastConnection(id: string){
    let meses = new Map<string, string>([
      ["01", "enero"],
      ["02", "febrero"],
      ["03", "marzo"],
      ["04", "abril"],
      ["05", "mayo"],
      ["06", "junio"],
      ["07", "julio"],
      ["08", "agosto"],
      ["09", "septiembre"],
      ["10", "octubre"],
      ["11", "noviembre"],
      ["12", "diciembre"],
    ]);

    let usrFil = this.users.filter(user => user.IDUSUARIO == id);
    let usr = usrFil[0];
    let lastCon = usr.ULCON;
    if(lastCon == null){
      return "-";
    }

    let dateTimeArr = lastCon.split(" ");
    let dateArr = dateTimeArr[0].split("-");
    let timeArr = dateTimeArr[1].split(":");

    let tiempo = parseInt(timeArr[0]) > 12 ? "PM": "AM";
    let hora = parseInt(timeArr[0]) > 12 ? parseInt(timeArr[0]) - 12 : parseInt(timeArr[0]);
    let horaStr = hora < 10 ? `0${hora}` : hora;

    let la = hora == 1 ? "la" : "las";

    return `El ${dateArr[2]} de ${meses.get(dateArr[1])} del ${dateArr[0]} a ${la} ${horaStr}:${timeArr[1]} ${tiempo}`
  }

  buildName(na: string, fl: string, sl: string | undefined){
    let name = na + " " + fl;
    if(typeof sl == 'undefined' || sl == ""){
      name += " " + sl;
    }

    return name;
  }

  async openConnections(id: string){
    let idEnc = await this._encService.encriptar(id);
    this._router.navigate(['sam/ADSI/MAUS/detalles'], {
      queryParams: {
        info: idEnc
      }
    });
  }

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