import { Injectable } from "@angular/core";
import { HttpClient } from "@angular/common/http";

import { BehaviorSubject, Observable } from "rxjs";
import { map } from "rxjs/operators";

import { User } from "../models/user";
import { BaseService } from "./base.service";

@Injectable({
  providedIn: "root"
})
export class AuthenticationService extends BaseService {
  private currentUserSubject: BehaviorSubject<User>;
  public currentUser: Observable<User>;

  constructor(private http: HttpClient) {
    super();

    this.currentUserSubject = new BehaviorSubject<User>(
      JSON.parse(localStorage.getItem("currentUser"))
    );
    this.currentUser = this.currentUserSubject.asObservable();

    this.alwaysLogin();
  }

  public get currentUserValue(): User {
    return this.currentUserSubject.value;
  }

  public login(username: string, password: string) {
    const bodyLogin = {
      login: username,
      password: password
    };

    return this.http
      .post<User>(`${this.apiUrl}/User/Authenticate`, bodyLogin, {
        headers: this.headers
      })
      .pipe(
        map(user => {
          // store user details and basic auth credentials in local storage to keep user logged in between page refreshes
          user.authdata = window.btoa(username + ":" + password);
          localStorage.setItem("currentUser", JSON.stringify(user));
          this.currentUserSubject.next(user);
          return user;
        })
      );
  }

  public create(newUser: User) {
    return this.http
      .post<any>(`${this.apiUrl}/User`, newUser, {
        headers: this.headers
      })
      .pipe(
        map(result => {
          this.login(newUser.login, newUser.password);
        })
      );
  }

  private alwaysLogin() {
    return this.http.get(`${this.apiUrl}/User/AlwayLogin`, {
      headers: this.headers
    });
  }

  logout() {
    // remove user from local storage to log user out
    localStorage.removeItem("currentUser");
    this.currentUserSubject.next(null);
  }
}
