import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, throwError, Observable, of } from 'rxjs';
import { map, catchError } from 'rxjs/operators';

import { HitAWodService } from './hit-a-wod.service';
import { TokenService } from './token.service';
import { UserService } from './user.service';
import { User } from '../models/user.model';
import { SubscriptionService } from './subscription.service';

@Injectable({
  providedIn: 'root'
})
export class AuthenticationService {
  private loggedIn = new BehaviorSubject<boolean>(this.token.loggedIn());
  authStatus = this.loggedIn.asObservable();
  private rolesPermitted:string[] = ["coach", "box_admin", "company_admin", "super_admin"];

  constructor(private token:TokenService,
              private api:HitAWodService,
              private userService:UserService) {}

  login(username: string, password: string, custom_user_id:string = null) {
      return this.api.login({email: username, password: password}, custom_user_id).pipe(
        map((response:any) => {
            // store user details and jwt token in local storage to keep user logged in between page refreshes
            if(response.user && response.access_token) {
              let u:User = response.user;
              u.subscriptions_selections = response.subscriptions;
              this.userService.setUser(u);
              if(this.isRolePermitted()) {
                this.token.handle(response.access_token);
                this.changeAuthStatus(true);
  
                return response;
              }
              else {
                this.userService.deleteUser();
                return { error: true, message: "Solo pueden iniciar sesión los coach y administradores. Consulta tu administrador."};
              };
            } 
            
            return response;
        })
      );
  }

  logout() {
      // remove user from local storage to log user out
      this.token.remove();
      this.userService.deleteUser();
      //this.subscriptionService.removeSubscription();
      this.changeAuthStatus(false);
  }

  refreshToken() {
    return this.api.refreshToken().pipe(
      map(response => {
        let u:User = response.user;
        u.subscriptions_selections = response.subscriptions;
        this.userService.setUser(u);
        this.token.handle(response.access_token);
        this.changeAuthStatus(true);
        return true;
      }),
      catchError(err => {
        return of(false);
      })
    );
  }

  currentAuthStatus():boolean {
    return this.loggedIn.value;
  }
  
  isRolePermitted():boolean {
    for(let i = 0; i<this.userService.currentUserValue.subscriptions_selections.length; i++) {
      const sub = this.userService.currentUserValue.subscriptions_selections[i];
      if(this.isRoleOk(sub.role.slug)) {
        return true;
      }
    }
    return false;
  }

  isRoleOk(slug:string) {
    return this.rolesPermitted.includes(slug);
  }

  changeAuthStatus(value:boolean) {
      this.loggedIn.next(value);
  }

}