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 TOKEN = "TOKEN";
  private loggedUser: string;

  constructor(private http: HttpClient) {}

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

  logout() {
    let refreshToken: string = this.getRefreshToken();

    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}/token/refresh/`, {
        token: `${refreshToken}`
      })
      .pipe(
        tap((tokens: Token) => {
          this.storeJwtToken(tokens["token"]);
        }, catchError(this.errorHandl))
      );
  }

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

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

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

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

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

  private storeTokens(tokens: Token) {
    localStorage.setItem(this.TOKEN, tokens["token"]);
  }

  removeTokens() {
    localStorage.removeItem(this.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);
  }
}
