import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { ResourcesService } from 'src/app/services/resources/resources.service';
import { LoginPlace } from './../../interfaces/user-connections.interface';
import { GeolocationService } from '@ng-web-apis/geolocation';
import { GeolocationService as Gservice } from 'src/app/services/geolocation.service';
import { Permissions } from 'src/app/interfaces/permissions.interface';
import { take, lastValueFrom } from 'rxjs';
import { GeolocationResponse } from 'src/app/interfaces/location-response.interface';
import { LoginResponse } from 'src/app/interfaces/login.interface';
import { Router } from '@angular/router';
import { LoginService } from 'src/app/services/login/login.service';
import { EncService } from 'src/app/services/enc/enc.service';
import { LoginDataService } from 'src/app/services/login/login-data.service';
import { MaintenanceStatusResponse } from 'src/app/interfaces/maintenance-status.interface';
import { SystemAdminService } from 'src/app/services/system-admin.service';


@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css'],
})
export class LoginComponent implements OnInit {

  public formGroup: FormGroup;
  public hide:boolean;
  public isLoading:boolean;

  constructor(
    private router: Router,
    private _serviceLogin: LoginService,
    private _resourceService: ResourcesService,
    private readonly geolocation$: GeolocationService,
    private _loginDataService: LoginDataService,
    private _encService: EncService,
    private _systemAdminService: SystemAdminService,
    private _geolocationService: Gservice,
  ) {
    this.formGroup = this.createFormGroup();
    this.hide = true;
    this.isLoading = false;
  }

  ngOnInit(): void { }

  private createFormGroup() {
    return new FormGroup({
      email: new FormControl('', [Validators.required, Validators.email]),
      password: new FormControl('', Validators.required),
    });
  }


  public login() {
    this.isLoading = true;
    if(!this.email?.valid){
      this._resourceService.openSnackBar("El correo electrónico es un campo obligatorio.");
      return;
    }

    if(!this.password?.valid){
      this._resourceService.openSnackBar("La contraseña es un campo obligatorio.");
      return;
    }

    this.geolocation$.pipe(take(1)).subscribe(position => {
      let userPosition: LoginPlace = {
        latitude: position.coords.latitude,
        longitude: position.coords.longitude,
        accuracy: position.coords.accuracy
      };

      this.requestLogin(userPosition);
    });
  }

  public getErrorMessage(type:string) {
    if (type === 'EMAIL' && this.email?.hasError('email')) {
      return 'No es un correo electrónio válido.';
    }
    if (type === 'EMAIL' && this.email?.hasError('required')) {
      return 'El campo Correo Electrónico es obligatorio.';
    }
    if (type === 'PASSW' && this.password?.hasError('required')) {
      return 'El campo Contraseña es obligatorio.';
    }
    return '';
  }

  async requestLogin(position: LoginPlace){
    try{
      let pwdEnc = await this._encService.encriptar(this.password?.value);
      let loginPlace: GeolocationResponse | boolean = await this._getPlace(position);

      if(!loginPlace){
        this._resourceService.openSnackBar('No se pudo obtener la ubicación del usuario, por favor intente más tarde.');
        this.isLoading = false;
      }else{
        let location: GeolocationResponse = loginPlace as GeolocationResponse;

        let lati = position.latitude;
        let long = position.longitude;
        let prec = position.accuracy;

        let ciud = location.locality;
        // let esta = 'Morelos';
        let esta = location.city;
        let pais = location.countryName;

        let loginResponse: LoginResponse = await lastValueFrom(this._serviceLogin.login({
          email: this.email?.value,
          password: pwdEnc,
          linea: 1,
          latitude: lati,
          longitude: long,
          accuracy: prec,
          city: ciud,
          state: esta,
          country: pais,
        }));


        if (loginResponse.error == false) {
          let shortEnc = await lastValueFrom(this._encService.shortEncrypt(loginResponse.response.IDUSUARIO));
          let maintenanceStatus: MaintenanceStatusResponse = await lastValueFrom(this._systemAdminService.getMaintenanceStatus(
            shortEnc.response.encrypted, 1, loginResponse.response.TOKEN
          ));

          if(maintenanceStatus.response.activated){
            let permisosDec = await this._encService.desencriptar(loginResponse.response.PERMISOS);
            let permisosArr: Permissions = JSON.parse(permisosDec);

            let systemAdmin = permisosArr.permissions.filter(mod => mod.id == 'S002V01M01ADSI')[0];
            if(systemAdmin.access != 0){
              let maintenanceMode = systemAdmin.children.filter(func => func.id == 'S002V01F05MOMA')[0];

              if(maintenanceMode.access != 0){
                let activateMaintenance = maintenanceMode.children.filter(scr => scr.id == 'S002V01P01AMMA')[0];

                if(activateMaintenance.access == 2){
                  let maintenance = await this._encService.encriptar(JSON.stringify({
                    idUser: loginResponse.response.IDUSUARIO,
                    maintenance: 'enabled',
                  }));

                  this._loginDataService.saveLoginInformation(
                    loginResponse.response.TOKEN,
                    loginResponse.response.IDUSUARIO,
                    loginResponse.response.NOMBREUSUARIO,
                    loginResponse.response.CORREO,
                    loginResponse.response.PERFIL,
                    loginResponse.response.PERMISOS
                  );

                  this.router.navigate(['sam/home'], { queryParams: { data: maintenance } });
                }else{
                  this.isLoading = false;
                  this._resourceService.openSnackBar("Lo sentimos, en este momento el sistema se encuentra en modo mantenimiento.");
                }
              }else{
                this.isLoading = false;
                this._resourceService.openSnackBar("Lo sentimos, en este momento el sistema se encuentra en modo mantenimiento.");
              }
            }else{
              this.isLoading = false;
              this._resourceService.openSnackBar("Lo sentimos, en este momento el sistema se encuentra en modo mantenimiento.");
            }
          }else{
            this._loginDataService.saveLoginInformation(
              loginResponse.response.TOKEN,
              loginResponse.response.IDUSUARIO,
              loginResponse.response.NOMBREUSUARIO,
              loginResponse.response.CORREO,
              loginResponse.response.PERFIL,
              loginResponse.response.PERMISOS
            );

            this.router.navigate(['sam/home']);
          }
        }
      }

    }catch(error: any){
      let msgError = "";

      if(error.error !== undefined){
        msgError = error.error.msg;
      }else{
        msgError = "Ocurrió un error inesperado.";
      }

      this._resourceService.openSnackBar(msgError);
      this.isLoading = false;
    }
  }

  async _getPlace(coords: LoginPlace): Promise<GeolocationResponse | boolean>{
    try{
      let location: GeolocationResponse = await lastValueFrom(this._geolocationService.getLocationName(coords));

      return location;
    }catch(error: any){
      let msgError = "";

      if(error.error !== undefined){
        msgError = error.error.msg;
      }else{
        msgError = "Ocurrió un error inesperado.";
      }

      this._resourceService.openSnackBar(msgError);

      return false;
    }
  }

  get email() {
    return this.formGroup.get('email');
  }

  get password() {
    return this.formGroup.get('password');
  }
}
