import { Injectable } from '@angular/core';
import { Observable, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { CookieService } from 'src/app/service/cookie.service';
import { ContextPathService } from 'src/app/service/context-path.service';
import { Router } from '@angular/router';

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  isLoggedIn = false;

  locationUrl = '';

  logoutCallbacks = [];

  constructor(
    private http:HttpClient,
    private cookieService:CookieService,
    private contextPathService:ContextPathService,
    private router:Router,
  ) {
    if (!window.performance.navigation.type) {
      this.isLoggedIn = false;
    } else {
      this.isLoggedIn = !!localStorage.getItem('currentUser') && !!this.cookieService.get('authtkt');
    }
  }

  login(username:string, password:string, loginMethod:string = 'username'):Observable<boolean> {
    this.cookieService.set('login_method', loginMethod);
    const form = new FormData();
    form.append('login', username);
    form.append('password', password);
    form.append('method', loginMethod);
    const requestOptions:Record<string, unknown> = {
      /* other options here */
      responseType: 'json', // not a json
    };
    return this.http
      .post<any>(
        this.contextPathService.resolvePath('login_handler'),
        form,
        requestOptions,
      )
      .pipe(
        map((resp:any) => {
          const user = resp;
          // login successful if there's a jwt token in the response
          if (user) {
            // store user details and jwt token in local storage to keep user logged in between page refreshes
            localStorage.setItem('currentUser', escape(JSON.stringify(user)));
            this.isLoggedIn = true;
            return user;
          }
          throw new Error('Fail Auth');
        }),

        catchError((err:HttpErrorResponse) => {
          // TODO wrong code
          this.isLoggedIn = false;
          return throwError(err);
        }),
      );
  }

  logout():void {
    // remove user from local storage to log user out
    if (localStorage.getItem('currentUser')) {
      localStorage.removeItem('currentUser');
      this.cookieService.set('authtkt', 'reset');
      (this.logoutCallbacks || []).forEach(fn => {
        fn();
      });
      this.http.get('/api/logout_handler', {}).subscribe(
        (res) => {
          this.router.navigate(['/login']);
        },
        (err) => {
          this.router.navigate(['/login']);
        },
      );
    } else {
      this.router.navigate(['/login']);
    }
    this.isLoggedIn = false;
  }
}
