import { Inject, Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { AppLogsService } from '../applogs.service';
import { cnst_IP_ADDRESS_SOURCE_URL } from '../../consts';
import { AuthorizeService } from '../authorize.service';
import { ENVIRONMENT_TOKEN, IENVIRONMENT } from '../../injection-tokens';

@Injectable({
  providedIn: 'root'
})
export class RepositoryService {
  public authService: AuthorizeService;
  private apiUrl: string;

  constructor(
    private httpClient: HttpClient,
    private appLogService: AppLogsService,
    @Inject(ENVIRONMENT_TOKEN) environment: IENVIRONMENT,
  ) {
    this.apiUrl = environment.apiUrl;
  }

  // tslint:disable-next-line: no-shadowed-variable
  deleteDataById<T>(routing: string, id: string | number): Observable<T> {
    // tslint:disable-next-line: triple-equals
    const filterstr = (id && id != '0' ? '/' + id.toString() : '');
    return this.httpClient.delete<T>(this.apiUrl + '/' + routing + filterstr).pipe(map(response => response as T));
  }

  getDataById<T>(routing: string, id: string | number): Observable<T> {
    // tslint:disable-next-line: triple-equals
    const filterstr = (id && id != '0' && id != -1 ? '/' + id.toString() : '');
    return this.getDataByURLFilter<T>(routing, filterstr);
  }


  putDataById<T>(routing: string, id: string | number, obj: any): Observable<T> {
    // tslint:disable-next-line: triple-equals
    //      if (id && !Number.isNaN(Number(id)) && id != '0')
    return this.putData<T>(routing + '/' + id.toString(), obj);
  }


  postDataById<T>(routing: string, id: string | number, obj: any): Observable<T> {
    // tslint:disable-next-line: triple-equals
    let suffix: string = '';
    if (typeof id === 'number' || !Number.isNaN(Number(id))) {
      if (Number(id) > 0) suffix = id.toString();
    } else suffix = id;
    const filterstr = (suffix ? '/' + suffix : '');
    return this.postData<T>(routing + filterstr, obj);
  }


  getDataByObjFilter<T>(routing: string, filter: any): Observable<T> {
    this.appLogService.dlog('filter=', filter);
    return this.postData<T>(routing + (filter.filterPrefix ? '/' + filter.filterPrefix : ''), filter);
  }


  getDataByURLFilter<T>(routing: string, filter: string): Observable<T> {
    return this.getData<T>(routing + (filter && filter !== '' ? ((<string>filter).slice(0, 1) !== '/' ? '/' : '') + filter : '')/*, getMethodName()*/);
  }

  public putData<T>(routing: string, obj: any, headers?: HttpHeaders): Observable<T> {
    return this.httpClient.put<T>(this.apiUrl + '/' + routing, obj, { headers: headers }).pipe(map(response => response as T));
  }


  public postData<T>(routing: string, obj: any, headers?: HttpHeaders): Observable<T> {
    return this.httpClient.post<T>(this.apiUrl + '/' + routing, obj, { headers: headers }).pipe(map(response => response as T));
  }

  public getData<T>(routing: string, headers?: HttpHeaders): Observable<T> {
    return this.httpClient.get<T>(this.apiUrl + '/' + routing, { headers: headers }).pipe(map(response => response as T));
  }

  public getIPAddress(): Observable<any> {
    return this.httpClient.get(cnst_IP_ADDRESS_SOURCE_URL);
  }

  // public async getData<T>(routing: string, headers?: HttpHeaders): Promise<Observable<T>> {
  //   return this.httpClient.get<T>(this.apiUrl + '/' + routing, { headers: headers })
  //     .pipe(
  //       map(response => of(response as T))
  //       , catchError(async (error: any) => {
  //         return of(null);
  //       })).toPromise();
  // }

}
