import { ActiveSessionsNumberResponse } from './../../../interfaces/active-sessions-number.interface';
import { SessionsDurationsInterface } from './../../../interfaces/sessions-duration.interface';
import { PasswordFormatResponse } from './../../../interfaces/password-format.interface';
import { MatSnackBar } from '@angular/material/snack-bar';
import { MatTableDataSource } from '@angular/material/table';
import { UsersAuth, UserAuth } from './../../../interfaces/user-auths.interface';
import { lastValueFrom } from 'rxjs';
import { EncService } from './../../../services/enc/enc.service';
import { SystemAdminService } from './../../../services/system-admin.service';
import { FormBuilder, FormControl } from '@angular/forms';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-security-politics',
  templateUrl: './security-politics.component.html',
  styleUrls: ['./security-politics.component.css']
})
export class SecurityPoliticsComponent implements OnInit {
  isLoading: boolean;
  hasError: boolean;
  errorStr: string;
  users: UserAuth[] = [];

  politicsForm = this._formBuilder.group({
    enableMinLength: true,
    minLength: '8',
    enableUpperCase: true,
    minUpper: new FormControl({value: '1', disabled: false}),
    enableNumbers: true,
    minNumber: new FormControl({value: '1', disabled: false}),
    enableCharacters: true,
    minCharacters: new FormControl({value: '1', disabled: false})
  });

  sessionsForm = this._formBuilder.group({
    days: '1',
    hours: '0',
    minutes: '0',
    seconds: '0',
  });

  sessionsNumberForm = this._formBuilder.group({
    number: '3',
  });

  dataSourceAuth?: MatTableDataSource<UserAuth>;
  displayedColumnsAuth = ['ID', 'NAME', 'AUTH'];

  constructor(
    private _formBuilder: FormBuilder,
    private _systemAdminService: SystemAdminService,
    private _encService: EncService,
    private _snackBar: MatSnackBar,
  ) { 
    this.isLoading = true;
    this.hasError = false;
    this.errorStr = "";
  }

  ngOnInit(): void {
    this.getAuthData();
  }

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

  async getAuthData(){
    try{
      let idUser = localStorage.getItem('idusuario');
      let shortEnc = await lastValueFrom(this._encService.shortEncrypt(idUser!));
      let userAuths: UsersAuth = await lastValueFrom(this._systemAdminService.getTwoStepsAuth(shortEnc.response.encrypted, 1));
      this.users = [];

      let cont = 0;
      userAuths.response.forEach(async (item: UserAuth) => {
        let idDec = await this._encService.desencriptar(item.IDUSUARIO);
        let id = await this._encService.desencriptar(idUser!);

        if(idDec != id){
          let usr: UserAuth = {
            IDUSUARIO: idDec,
            NOMBREUSUARIO: item.NOMBREUSUARIO,
            AUTHENABLED: item.AUTHENABLED
          };

          this.users.push(usr);
        }
        
        cont++;
        if(cont == userAuths.response.length){
          this.dataSourceAuth = new MatTableDataSource(this.users);
          this.getPwdData();
        }
      });
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado.';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado.';
      }else{
        this.errorStr = error.error.msg;
      }

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

  async savePaswordFormat(){
    try{
      var passwordForm = new FormData();
      let config = this.politicsForm.getRawValue();
      let idUser = localStorage.getItem('idusuario');

      passwordForm.append('id_user', idUser!);
      passwordForm.append('linea', '1');
      passwordForm.append('min_length', config.minLength!);
      passwordForm.append('upper_enabled', config.enableUpperCase ? '1' : '0');
      passwordForm.append('min_upper', config.minUpper!);
      passwordForm.append('number_enabled', config.enableNumbers ? '1' : '0');
      passwordForm.append('min_number', config.minNumber!);
      passwordForm.append('chars_enabled', config.enableCharacters ? '1' : '0');
      passwordForm.append('min_chars', config.minCharacters!);

      await lastValueFrom(this._systemAdminService.savePasswordFormat(passwordForm));

      this.isLoading = true;
      this.hasError = false;
      this.errorStr = "";

      this.getAuthData();
    }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.openSnackBar(msg);
    }
  }

  async saveSessionsDuration(){
    try{
      var passwordForm = new FormData();
      let config = this.sessionsForm.getRawValue();
      let idUser = localStorage.getItem('idusuario');

      passwordForm.append('id_user', idUser!);
      passwordForm.append('linea', '1');
      passwordForm.append('days', config.days!);
      passwordForm.append('hours', config.hours!);
      passwordForm.append('minutes', config.minutes!);
      passwordForm.append('seconds', config.seconds!);

      await lastValueFrom(this._systemAdminService.saveSessionsDuration(passwordForm));

      this.isLoading = true;
      this.hasError = false;
      this.errorStr = "";

      this.getAuthData();
    }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.openSnackBar(msg);
    }
  }

  async saveActiveSessionsNumber(){
    try{
      var passwordForm = new FormData();
      let config = this.sessionsNumberForm.getRawValue();
      let idUser = localStorage.getItem('idusuario');

      passwordForm.append('id_user', idUser!);
      passwordForm.append('linea', '1');
      passwordForm.append('sessions', config.number!);

      await lastValueFrom(this._systemAdminService.saveActiveSessionsNumber(passwordForm));

      this.isLoading = true;
      this.hasError = false;
      this.errorStr = "";

      this.getAuthData();
    }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.openSnackBar(msg);
    }
  }

  async getPwdData(){
    try{
      let idUser = localStorage.getItem('idusuario');
      let shortEnc = await lastValueFrom(this._encService.shortEncrypt(idUser!));
      let pwdFormat: PasswordFormatResponse = await lastValueFrom(this._systemAdminService.getPasswordFormat(shortEnc.response.encrypted, 1));

      this.politicsForm.controls.minLength.setValue(`${pwdFormat.response.password_format.min_length}`);
      this.politicsForm.controls.enableUpperCase.setValue(pwdFormat.response.password_format.upper_enabled);
      this.politicsForm.controls.minUpper.setValue(`${pwdFormat.response.password_format.min_upper}`);

      if(!pwdFormat.response.password_format.upper_enabled){
        this.politicsForm.controls.minUpper.disable();
      }

      this.politicsForm.controls.enableNumbers.setValue(pwdFormat.response.password_format.number_enabled);
      this.politicsForm.controls.minNumber.setValue(`${pwdFormat.response.password_format.min_number}`);

      if(!pwdFormat.response.password_format.number_enabled){
        this.politicsForm.controls.minNumber.disable();
      }

      this.politicsForm.controls.enableCharacters.setValue(pwdFormat.response.password_format.chars_enabled);
      this.politicsForm.controls.minCharacters.setValue(`${pwdFormat.response.password_format.min_chars}`);

      if(!pwdFormat.response.password_format.chars_enabled){
        this.politicsForm.controls.minCharacters.disable();
      }
      
      this.getSessionsData();
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado.';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado.';
      }else{
        this.errorStr = error.error.msg;
      }

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

  async getSessionsData(){
    try{
      let idUser = localStorage.getItem('idusuario');
      let shortEnc = await lastValueFrom(this._encService.shortEncrypt(idUser!));
      let sessionsDuration: SessionsDurationsInterface = await lastValueFrom(this._systemAdminService.getSessionsDuration(shortEnc.response.encrypted, 1));

      this.sessionsForm.controls.days.setValue(`${sessionsDuration.response.sessions_duration.days}`);
      this.sessionsForm.controls.hours.setValue(`${sessionsDuration.response.sessions_duration.hours}`);
      this.sessionsForm.controls.minutes.setValue(`${sessionsDuration.response.sessions_duration.minutes}`);
      this.sessionsForm.controls.seconds.setValue(`${sessionsDuration.response.sessions_duration.seconds}`);
      
      this.getActiveSessionsNumber();
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado.';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado.';
      }else{
        this.errorStr = error.error.msg;
      }

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

  async getActiveSessionsNumber(){
    try{
      let idUser = localStorage.getItem('idusuario');
      let shortEnc = await lastValueFrom(this._encService.shortEncrypt(idUser!));
      let activeSessionsNumber: ActiveSessionsNumberResponse = await lastValueFrom(this._systemAdminService.getActiveSessionsNumber(shortEnc.response.encrypted, 1));

      this.sessionsNumberForm.controls.number.setValue(`${activeSessionsNumber.response.active_sessions_number}`);

      this.hasError = activeSessionsNumber.error;
      this.errorStr = activeSessionsNumber.msg;
      this.isLoading = false;
    }catch(error: any){
      if(error.error == undefined){
        this.errorStr = 'Ocurrió un error inesperado.';
      }else if(error.error.msg == undefined){
        this.errorStr = 'Ocurrió un error inesperado.';
      }else{
        this.errorStr = error.error.msg;
      }

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

  async changeStatus(index: number){
    try{
      let item = this.users[index];
      let usersAux = this.users;
      
      item.AUTHENABLED = !item.AUTHENABLED;
      this.users = [];
  
      usersAux.forEach(user => {
        if(user.IDUSUARIO == item.IDUSUARIO){
          this.users.push(item);
        }else{
          this.users.push(user);
        }
      });
  
      this.dataSourceAuth = new MatTableDataSource(this.users);
      let usrEnc = await this._encService.encriptar(item.IDUSUARIO);
      let usrShort = await lastValueFrom(this._encService.shortEncrypt(usrEnc));
      let idUser = localStorage.getItem('idusuario');
      let idShort = await lastValueFrom(this._encService.shortEncrypt(idUser!));

      await lastValueFrom(this._systemAdminService.setTwoStepsAuth({
        id_user: idShort.response.encrypted,
        usuario: usrShort.response.encrypted,
        factor_doble: item.AUTHENABLED ? 'Si' : 'No',
        linea: 1
      }));
    }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.openSnackBar(msg);
    }
  }

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

  editMinLength(action: number){
    let minLengthStr = this.politicsForm.getRawValue().minLength;
    let minLength = parseInt(minLengthStr!);
    if(action == 0){
      if(minLength > 8){
        minLength--;
        this.politicsForm.controls.minLength.setValue(`${minLength}`);
      }
    }else{
      if(minLength < 30){
        minLength++;
        this.politicsForm.controls.minLength.setValue(`${minLength}`);
      }
    }
  }

  editMinUpper(action: number){
    let minUpperStr = this.politicsForm.getRawValue().minUpper;
    let minUpper = parseInt(minUpperStr!);
    if(action == 0){
      if(minUpper > 1){
        minUpper--;
        this.politicsForm.controls.minUpper.setValue(`${minUpper}`);
      }
    }else{
      if(minUpper < 10){
        minUpper++;
        this.politicsForm.controls.minUpper.setValue(`${minUpper}`);
      }
    }
  }

  disableMinUpper(){
    let isDisabled = this.politicsForm.controls.minUpper.disabled;
    if(isDisabled){
      this.politicsForm.controls.minUpper.enable();
    }else{
      this.politicsForm.controls.minUpper.disable();
    }
  }

  editMinNumber(action: number){
    let minNumberStr = this.politicsForm.getRawValue().minNumber;
    let minNumber = parseInt(minNumberStr!);
    if(action == 0){
      if(minNumber > 1){
        minNumber--;
        this.politicsForm.controls.minNumber.setValue(`${minNumber}`);
      }
    }else{
      if(minNumber < 10){
        minNumber++;
        this.politicsForm.controls.minNumber.setValue(`${minNumber}`);
      }
    }
  }

  disableMinNumber(){
    let isDisabled = this.politicsForm.controls.minNumber.disabled;
    if(isDisabled){
      this.politicsForm.controls.minNumber.enable();
    }else{
      this.politicsForm.controls.minNumber.disable();
    }
  }

  editMinCharacters(action: number){
    let minCharactersStr = this.politicsForm.getRawValue().minCharacters;
    let minCharacters = parseInt(minCharactersStr!);
    if(action == 0){
      if(minCharacters > 1){
        minCharacters--;
        this.politicsForm.controls.minCharacters.setValue(`${minCharacters}`);
      }
    }else{
      if(minCharacters < 10){
        minCharacters++;
        this.politicsForm.controls.minCharacters.setValue(`${minCharacters}`);
      }
    }
  }

  disableMinCharacters(){
    let isDisabled = this.politicsForm.controls.minCharacters.disabled;
    if(isDisabled){
      this.politicsForm.controls.minCharacters.enable();
    }else{
      this.politicsForm.controls.minCharacters.disable();
    }
  }

  editDays(action: number){
    let daysStr = this.sessionsForm.getRawValue().days;
    let days = parseInt(daysStr!);
    if(action == 0){
      if(days > 0){
        days--;
        this.sessionsForm.controls.days.setValue(`${days}`);
      }
    }else{
      if(days < 30){
        days++;
        this.sessionsForm.controls.days.setValue(`${days}`);
      }
    }
  }

  editHours(action: number){
    let hoursStr = this.sessionsForm.getRawValue().hours;
    let hours = parseInt(hoursStr!);
    if(action == 0){
      if(hours > 0){
        hours--;
        this.sessionsForm.controls.hours.setValue(`${hours}`);
      }
    }else{
      if(hours < 23){
        hours++;
        this.sessionsForm.controls.hours.setValue(`${hours}`);
      }
    }
  }

  editMinutes(action: number){
    let minutesStr = this.sessionsForm.getRawValue().minutes;
    let minutes = parseInt(minutesStr!);
    if(action == 0){
      if(minutes > 0){
        minutes--;
        this.sessionsForm.controls.minutes.setValue(`${minutes}`);
      }
    }else{
      if(minutes < 59){
        minutes++;
        this.sessionsForm.controls.minutes.setValue(`${minutes}`);
      }
    }
  }

  editSeconds(action: number){
    let secondsStr = this.sessionsForm.getRawValue().seconds;
    let seconds = parseInt(secondsStr!);
    if(action == 0){
      if(seconds > 0){
        seconds--;
        this.sessionsForm.controls.seconds.setValue(`${seconds}`);
      }
    }else{
      if(seconds < 59){
        seconds++;
        this.sessionsForm.controls.seconds.setValue(`${seconds}`);
      }
    }
  }

  editNumber(action: number){
    let numStr = this.sessionsNumberForm.getRawValue().number;
    let num = parseInt(numStr!);
    if(action == 0){
      if(num > 1){
        num--;
        this.sessionsNumberForm.controls.number.setValue(`${num}`);
      }
    }else{
      if(num < 5){
        num++;
        this.sessionsNumberForm.controls.number.setValue(`${num}`);
      }
    }
  }
}
