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

@Injectable({
  providedIn: 'root'
})
export class LoginDataService {
  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, panel: string | null) {
    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)

    if(panel != null){
      this.localStorageLogin.setItem('panel', panel)
    }

    let socketInfoObj = {
      token: token,
      user: idusuario
    };

    let socketInfoStr = JSON.stringify(socketInfoObj);
    this._socketService.saveSession(socketInfoStr);
  }

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

      if(resp.error){
        return false;
      }else{
        return resp.response.validToken;
      }
    }catch(error: any){
      console.log(error);
      if(error instanceof HttpErrorResponse){
        console.log(error.status);
        console.log(error.error)
      }
      this._resourceService.openSnackBar('Ocurrió un error al validar el token');
      return true;
    }
  }

  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 () {
    let uriArr = window.location.href.split(':');
    if(uriArr[0] == 'https'){
      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);
      });
    }else{
      let userPosition: LoginPlace = {
        latitude: 19.3477,
        longitude: -99.1877,
        accuracy: 169665
      };

      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;
  
      let sessionData = {
        token: localStorage.getItem('token'),
        user: localStorage.getItem('idusuario')
      }

      let sessionDataStr = JSON.stringify(sessionData);
      this._socketService.deleteSession(sessionDataStr);

      this._socketService.unregister(id!);
      // this.localStorageLogin.clear()
      this.localStorageLogin.removeItem('correo');
      this.localStorageLogin.removeItem('idusuario');
      this.localStorageLogin.removeItem('nombre_usuario');
      this.localStorageLogin.removeItem('panel');
      this.localStorageLogin.removeItem('perfil');
      this.localStorageLogin.removeItem('permisos');
      this.localStorageLogin.removeItem('token');

      this.router.navigate(['login']);
      await lastValueFrom(this._connectionsServiece.setLastConnection({
        id: id,
        linea: 1,
        latitude: lati,
        longitude: long,
        accuracy: prec,
        city: ciud,
        state: esta,
        country: pais,
      }));
    }catch(error: any){
      this._socketService.unregister(id!);
      // this.localStorageLogin.clear()
      this.localStorageLogin.removeItem('correo');
      this.localStorageLogin.removeItem('idusuario');
      this.localStorageLogin.removeItem('nombre_usuario');
      this.localStorageLogin.removeItem('panel');
      this.localStorageLogin.removeItem('perfil');
      this.localStorageLogin.removeItem('permisos');
      this.localStorageLogin.removeItem('token');
      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;
    }
  }
}
