import { ValidToken } from './../../interfaces/valid-token.interface';
import { LoginService } from 'src/app/services/login/login.service';
import { SocketService } from './../socket.service';
import { ConnectionsService } from './../connections.service';
import { lastValueFrom, take } from 'rxjs';
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { EncService } from '../enc/enc.service';
import { GeolocationService } from '@ng-web-apis/geolocation';
import { GeolocationResponse } from 'src/app/interfaces/location-response.interface';
import { LoginPlace } from 'src/app/interfaces/user-connections.interface';
import { ResourcesService } from '../resources/resources.service';
import { GeolocationService as Gservice } from 'src/app/services/geolocation.service';

@Injectable({
  providedIn: 'root'
})
export class LoginDataService {
  public localStorageLogin

  constructor(
    private router: Router,
    private _encService: EncService,
    private _connectionsServiece: ConnectionsService,
    private _socketService: SocketService,
    private _loginService: LoginService,
    private readonly geolocation$: GeolocationService,
    private _resourceService: ResourcesService,
    private _geolocationService: Gservice,
  ) {
    this.localStorageLogin = localStorage
  }

  saveLoginInformation(token: string, idusuario: string, nombre_usuario: string, correo: string, perfil: string, permisos: string) {
    this.localStorageLogin.setItem('token', token)
    this.localStorageLogin.setItem('idusuario', idusuario)
    this.localStorageLogin.setItem('nombre_usuario', nombre_usuario)
    this.localStorageLogin.setItem('correo', correo)
    this.localStorageLogin.setItem('permisos', permisos)
    this.localStorageLogin.setItem('perfil', perfil)
  }

  async verifyToken(token: string): Promise<boolean>{
    try{
      let resp: ValidToken = await lastValueFrom(this._loginService.verifyToken(token));

      if(resp.error){
        return false;
      }else{
        return resp.response.validToken;
      }
    }catch(error: any){
      return false;
    }
  }

  showToken() {
    return this.localStorageLogin.getItem('token')
  }

  showIdusuario() {
    return this.localStorageLogin.getItem('idusuario')
  }

  showPerfil() {
    return this.localStorageLogin.getItem('perfil')
  }

  showNombreUsuario() {
    return this._encService.decrypt(this.localStorageLogin.getItem('nombre_usuario')!)
  }

  showCorreo() {
    return this._encService.decrypt(this.localStorageLogin.getItem('correo')!)
  }

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

      this.requestLogout(userPosition);
    });
  }

  async requestLogout(position: LoginPlace){
    let id = localStorage.getItem('idusuario');

    try{
      let loginPlace: GeolocationResponse | boolean = await this._getPlace(position);
      let location: GeolocationResponse = loginPlace as GeolocationResponse;

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

      let ciud = location.locality;
      let esta = location.city;
      let pais = location.countryName;

      await lastValueFrom(this._connectionsServiece.setLastConnection({
        id: id,
        linea: 1,
        latitude: lati,
        longitude: long,
        accuracy: prec,
        city: ciud,
        state: esta,
        country: pais,
      }));
  
      this._socketService.unregister(id!);
      // this.localStorageLogin.clear()
      this.localStorageLogin.removeItem('token');
      this.localStorageLogin.removeItem('idusuario');
      this.localStorageLogin.removeItem('nombre_usuario');
      this.localStorageLogin.removeItem('correo');
      this.localStorageLogin.removeItem('permisos');
      this.localStorageLogin.removeItem('perfil');

      this.router.navigate(['login']);

    }catch(error: any){
      this._socketService.unregister(id!);
      // this.localStorageLogin.clear()
      this.localStorageLogin.removeItem('token');
      this.localStorageLogin.removeItem('idusuario');
      this.localStorageLogin.removeItem('nombre_usuario');
      this.localStorageLogin.removeItem('correo');
      this.localStorageLogin.removeItem('permisos');
      this.localStorageLogin.removeItem('perfil');
      this.router.navigate(['login']);
    }
  }

  isLogin () {
    return this.localStorageLogin.getItem('token') != '' && this.localStorageLogin.getItem('token') != undefined && this.localStorageLogin.getItem('token') != null
  }


  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;
    }
  }
}
