import {EventEmitter, Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {ApiV1LoginResponse} from '../models/api-v1-login-response';
import {Router} from '@angular/router';
import {PeopleModel} from '../models/people.model';
import {UserExtraModel} from '../models/user-extra.model';
import {Observable} from 'rxjs';

@Injectable()
export class AuthService {

    public apiUrl = 'https://svr2021.lawipac.com:8080/api/v1/';
    public apiWsUrl = 'wss://svr2021.lawipac.com:8080/api/v1/ws';
    // public apiUrl = 'https://c5016.biukop.com.au:8080/api/v1/';
    // public apiWsUrl = 'wss://c5016.biukop.com.au:8080/api/v1/ws';
    public loggedIn = ApiV1LoginResponse.EmptyNew();
    loginSuccess = new EventEmitter <ApiV1LoginResponse>();

    constructor( private http: HttpClient ,
                 private router: Router) {
    }


    public AutoLogin(): void {
      const sfm: ApiV1LoginResponse = JSON.parse(localStorage.getItem('sfm'));
      if (!sfm) {
        console.log('no auto login');
        return;
      }
      this.loggedIn = new ApiV1LoginResponse(
        sfm.login,
        sfm.machineId,
        sfm.session,
        sfm.sessionExpire,
        sfm.role,
        new PeopleModel(
          sfm.User.Id, sfm.User.First, sfm.User.Last, sfm.User.Middle,
          sfm.User.Title, sfm.User.Display, sfm.User.Nick, sfm.User.Enabled)
      );

      if ( sfm.UserExtra !== undefined ) {
         this.loggedIn.UserExtra = new UserExtraModel(sfm.UserExtra);
      }

      this.loginSuccess.emit(this.loggedIn);
      // console.log ( 'auto login emit events',  this.loggedIn);
    }


    isAuthenticated(): boolean  {
      return this.loggedIn.login;
    }

    allowEditLoan(): boolean{
      return true;
    }

    saveSessionInfo(): void {
      localStorage.setItem('sfm', JSON.stringify(this.loggedIn));
      localStorage.setItem('mid', this.loggedIn.machineId);
    }

    login(email: string, password: string): void {

      this.http.post<ApiV1LoginResponse>(this.apiUrl + 'login', {u: email, p: password}).subscribe(
        responseData => {
           this.loggedIn.session = responseData['Biukop-Session'];
           this.loggedIn.login = responseData.login;
           this.loggedIn.machineId = responseData['Biukop-Mid'];
           this.loggedIn.sessionExpire = responseData.sessionExpire;
           this.loggedIn.role = responseData.role;
           if ( responseData.User !== undefined)  {
             this.loggedIn.User = new PeopleModel(
               responseData.User.Id,
               responseData.User.First,
               responseData.User.Last,
               responseData.User.Middle,
               responseData.User.Title,
               responseData.User.Display,
               responseData.User.Nick,
               responseData.User.Enabled,
             );

             if (responseData.UserExtra !== undefined ) {
                this.loggedIn.UserExtra = new UserExtraModel(responseData.UserExtra);
             }else{
               this.loggedIn.UserExtra = UserExtraModel.EmptyNew();
             }
           }else{
             this.loggedIn.User = PeopleModel.EmptyNew();
           }

           this.saveSessionInfo();
           this.loginSuccess.emit(responseData);
         },
        error => {
          this.loggedIn = ApiV1LoginResponse.EmptyNew();
          console.log('login error', error);
          this.loginSuccess.emit(this.loggedIn);
        }

      );
    }

    logout(): void {
       this.loggedIn = ApiV1LoginResponse.EmptyNew();
       localStorage.removeItem('sfm');
       this.loginSuccess.emit(this.loggedIn);
       this.router.navigate(['/login']).then(r => {
         console.log('prepare to log back in');
       } );
       this.http.post(`${this.apiUrl}logout`, '').subscribe(
          resp => {
            console.log('successfully logout from server');
          },
          event => {
            console.log('error logout from server', event);
          }
        );
    }


    public getUrl(key: string): string{
      const s = this.apiUrl + key;
      const kvPair: {key: string, value: string}[] = [
        {key: 'login',  value: this.apiUrl + 'login'},
        {key: 'logout', value: this.apiUrl + 'logout'}
      ];

      kvPair.forEach( item => {
          if  ( item.key === key) {
            return item.value;
          }
      });

      // not found if arrive here
      return s;
    }

    public UpdatePeopleInfo(people: PeopleModel): void{
      this.loggedIn.User.Display = people.Display;
      this.loggedIn.User.First = people.First;
      this.loggedIn.User.Last = people.Last;
      this.saveSessionInfo();
    }

    public LoginAvailable(v: string): Observable<boolean> {
      return this.http.get<boolean>(this.getUrl('login-available/' + v));
    }

    public isAdmin(): boolean {
      return this.loggedIn.role === 'admin';
    }

    public isBroker(): boolean {
      return this.loggedIn.role === 'broker';
    }

    public isUser(): boolean {
      return this.loggedIn.login === true;
    }

    public isCurrentUser(id: string): boolean {
        return this.loggedIn.login === true && this.loggedIn.User !== undefined && this.loggedIn.User.Id === id;
    }
}
