import { Cliente } from './../interface/cliente';
import { ErrorResponse } from './../interface/error-response';
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse} from  '@angular/common/http';
import { tap, catchError } from  'rxjs/operators';
import { Observable, BehaviorSubject, of} from  'rxjs';

import { Storage } from  '@ionic/storage';
import { AuthResponse } from  '../interface/auth-response';
import { UtilService } from '../../service/util.service';
import { HttpClientDataService } from '../../service/http-client-data.service';
import { Platform, Events } from '@ionic/angular';

@Injectable({
  providedIn: 'root'
})
export class AuthService {

  public result;

  constructor(
    private  httpClient:  HttpClient, 
    private  storage:  Storage, 
    private  utilService:  UtilService,
    private  httpClientDataService: HttpClientDataService,
    private  platform: Platform,
    private events: Events
    ) 
  { 
    this.errorRespose = { 
      error: true,
      errorMsg: ""
    };
    this.clientiSalvati = false;
    AuthService.clienti = [];
    AuthService.clienteSelezionato = {
      denominazione: null,
      id: null
    };
  }

  authSubject  =  new  BehaviorSubject(false);

  errorRespose : ErrorResponse;

  reset(value): Observable<ErrorResponse>{
    this.errorRespose.error = true;
    var param = UtilService.encodeBody({email: value.email});
    return this.httpClient.post<AuthResponse>(this.httpClientDataService.BASE_ADDRESS+'/autenticazione/resetpwd.do', param, this.httpClientDataService.httpOptions)
      .pipe(
      catchError(this.handleError),
      tap( (res:  AuthResponse ) => {

        if (!res.error) {
          this.errorRespose.error = false;
        }
        else{
          this.errorRespose.error = true;
          this.errorRespose.errorMsg = res.errorMsg;          
        }
      })
    );
  }

  static idReferente:string;
  static clienti:Cliente[];
  static clienteSelezionato: Cliente;
  private idClienteSelezionato;

  loadClienti()
  {
    return this.storage.get("clienti").then((data)=>{
      AuthService.clienti = data;
      AuthService.clienteSelezionato = AuthService.clienti[0];
      return data;
    });
  }

  setCliente(id)
  {
    this.idClienteSelezionato = id;
    AuthService.clienti.forEach(this.findCliente, this);
  }

  findCliente(cliente, index)
  {
    if(cliente.id == this.idClienteSelezionato) AuthService.clienteSelezionato = cliente;
  }

  getId()
  {
    return this.getFromStorageAsync("idUser").then(state => {
      return state;
    });
  }

  getFromStorageAsync(param){
    return this.storage.get(param).then((data)=>{
      AuthService.idReferente = data;
      return data;
    });
  }

  changePwd(value): Observable<ErrorResponse>{
    var param = UtilService.encodeBody({
      idutente: AuthService.idReferente,
      oldpassword: value.oldpassword,
      newpassword: value.newpassword
    });
    return this.httpClient.post<AuthResponse>(this.httpClientDataService.BASE_ADDRESS+'/autenticazione/changepwd.do', param, this.httpClientDataService.httpOptions)
      .pipe(
      catchError(this.handleError),
      tap( (res:  AuthResponse ) => {

        if (!res.error) {
          this.errorRespose.error = false;
        }
        else{
          this.errorRespose.error = true;
          this.errorRespose.errorMsg = res.errorMsg;          
        }
      })
    );
  }

  clientiSalvati: boolean;

  areClientiSalvati() : boolean
  {
    return this.clientiSalvati;
  }

  login(value) : Observable<ErrorResponse>{
    var param = UtilService.encodeBody({utente: value.username, password: value.password});
    this.clientiSalvati = false;
    return this.httpClient.post<ErrorResponse>(this.httpClientDataService.BASE_ADDRESS+'/autenticazione/login.do', param, this.httpClientDataService.httpOptions)
    .pipe(
      catchError(this.handleError),
      tap( (res:  AuthResponse ) => {
        if (!res.error) {
          this.authSubject.next(true);
            this.storage.set("idUser",res.id).then((successData)=>{
              console.log("Data Stored");
              console.log(successData);
            });
            this.storage.set("name",res.nome);
            this.storage.set("clienti", res.clienti).then((successData)=>{
              this.clientiSalvati = true;
              this.events.publish('functionCall:startup', null);
            });
            this.storage.set("logged",true);
          this.errorRespose.error = false;
        }
        else{
          this.errorRespose.error = true;
          this.errorRespose.errorMsg = res.errorMsg;          
        }
      })
    );
  }
  
  

  handleError(error: HttpErrorResponse) {
    this.errorRespose = { 
      error: true,
      errorMsg: ""
    };
    if (error.error instanceof ErrorEvent) {
      this.errorRespose.errorMsg = error.error.message;
    } else {
      this.errorRespose.errorMsg = error.error;
    }
    return of(this.errorRespose);
  };

  async logout() {
    this.storage.set("logged",false).then((successData)=>{
      console.log("Data Stored");
      console.log(successData);
    })
    this.authSubject.next(false);
  }

  isLoggedIn(){
    return this.storage.get("logged").then((data)=>{
      return data;
    });
  }

  async syncIsLoggedIn()
  {
    return await this.storage.get("logged");
  }
}
