import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { of, Observable, forkJoin, throwError } from 'rxjs';
import { catchError, mapTo, tap, map, mergeMap } from 'rxjs/operators';
import { Token } from '@app/models/token';
import { environment } from '@environments/environment';
import * as CryptoJS from 'crypto-js';
import Swal from 'sweetalert2';

@Injectable({
  providedIn: 'root'
})

export class AuthService {

  private readonly JWT_TOKEN = 'JWT_TOKEN';
  private readonly REFRESH_TOKEN = 'REFRESH_TOKEN';
  private readonly USER_MENU = 'USER_MENU';
  private loggedUser: string;

  constructor(private http: HttpClient) {}

  login(user: { email: string, password: string}): Observable<boolean> {
    return this.http.post<any>(`${environment.productionApiUrl}/auth/login`, user)
      .pipe(
        tap(tokens => this.doLoginUser(user.email, tokens)),
        mapTo(true),
        catchError(this.errorHandl)
      );
  }


  logout() {
    let refreshToken:string = this.getRefreshToken();
    this.http.post<any>(`${environment.productionApiUrl}/auth/logout`, {})
    .subscribe( results => {});
    this.http.post<any>(`${environment.productionApiUrl}/auth/logout2`, {}).subscribe( results => {
      this.doLogoutUser();
      Swal.close();  
      window.location.href = "";
    });
  }

  isLoggedIn() {
    return !!this.getJwtToken();
  }

  getUserLevel() {
    var bytes  = CryptoJS.AES.decrypt(localStorage.getItem("USER_MENU"), 'soma-inverlec-2019');
    var role_number = bytes.toString(CryptoJS.enc.Utf8);
    return role_number;
  }

  refreshToken() {
    let refreshToken:string = this.getRefreshToken();
    return this.http.post<any>(`${environment.productionApiUrl}/auth/refresh`, {
      'Authorization': `Bearer ${refreshToken}`
    }).pipe(tap((tokens: Token) => {
      this.storeJwtToken(tokens["data"]["access_token"]);
      },
      catchError(this.errorHandl)
    ));
  }

  getJwtToken() {
    return localStorage.getItem(this.JWT_TOKEN);
  }

  private doLoginUser(email: string, tokens: Token) {
    this.loggedUser = email;
    this.storeTokens(tokens);
  }

  private doLogoutUser() {
    this.loggedUser = null;
    this.removeTokens();
  }

  getRefreshToken() {
    return localStorage.getItem(this.REFRESH_TOKEN);
  }

  private storeJwtToken(jwt: string) {
    localStorage.setItem(this.JWT_TOKEN, jwt);
  }

  private storeTokens(tokens: Token) {
    localStorage.clear();
    localStorage.setItem(this.USER_MENU, CryptoJS.AES.encrypt(tokens["data"]["user"].role.toString(), 'soma-inverlec-2019').toString())
    localStorage.setItem(this.JWT_TOKEN, tokens["data"]["user"].token); 
    localStorage.setItem(this.REFRESH_TOKEN, tokens["data"]["user"].refresh);
  }

  removeTokens() {
    localStorage.removeItem(this.USER_MENU);
    localStorage.removeItem(this.JWT_TOKEN);
    localStorage.removeItem(this.REFRESH_TOKEN);
  }


  errorHandl(error) {
    let errorMessage = '';
    if(error.error) {
      // Get client-side error
      errorMessage = error.error;
    } else {
      // Get server-side error
      errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;      
    }
    return throwError(errorMessage);
  }

}