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();
  }

  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 => {
                        this.pushToken(username, password, user);
                        return user;
                    }));
  }

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

  public update(updatedUser: User) {
    return this.http.put<User>(`${this.apiUrl}/User/${updatedUser.id}`, 
                               updatedUser, 
                               { headers: this.headers })
                    .pipe(map(user => {
                      this.pushToken(updatedUser.login, updatedUser.password, user);
                      return user;
                    }));
  }

  private pushToken(login: string, password: string, user: User){
    if (user && user.token) {
      user.authdata = window.btoa(login + ":" + password);
      localStorage.setItem("currentUser", JSON.stringify(user));
      this.currentUserSubject.next(user);
    }
  }

  public alwaysLogin() {
    this.http.get(`${this.apiUrl}/User/AlwaysLogin`, 
                  { headers: this.headers })
             .subscribe(data => { console.log(data); });
  }

  public logout() {
    localStorage.removeItem("currentUser");
    this.currentUserSubject.next(null);
  }
}
