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

@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(error => {
          return of(false);
        }));
  }

  logout() {
    return this.http.post<any>(`${environment.productionApiUrl}/auth/logout`, {
    }).pipe(
      tap(() => this.doLogoutUser()),
      mapTo(true),
      catchError(error => {
        return of(false);
      }));
    }

  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"]);
    }));
  }

  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();
    //console.log(CryptoJS.AES.encrypt(this.JWT_TOKEN, tokens["data"]["user"].role.toString(), 'soma-inverlec-2019').toString());
    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);
  }

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