import { Injectable } from "@angular/core";
import {
  HttpClient,
  HttpHeaders,
  HttpErrorResponse
} from "@angular/common/http";
import { Observable, throwError, TimeoutError } from "rxjs";
import { catchError, retry, tap, timeout } from "rxjs/operators";
import { CommonService } from "../common/common.service";
//import { Response } from "../models/response";
import { Response } from 'src/app/hmg-common/services/models/response';

@Injectable({
  providedIn: "root"
})
export class ConnectorService {
  /*
  connection configuration settings
  */
  static httpOptions = {
    headers: new HttpHeaders({ "Content-Type": "application/json" })
  };
  public static retryTimes = 0;
  public static timeOut = 30 * 1000;
  //    public static host = 'http://10.50.100.113:6060/'; // development service

public static host = "https://uat.hmgwebservices.com/";
  //public static host = 'https://hmgwebservices.com/';
  // public static host = 'http://10.50.100.198:6060/';
  // public static host = 'http://10.50.100.113:6060/'; // development service
  /* public static host = 'http://10.50.100.198:6060/';
   public static host = 'http://10.50.100.198:6060/';    // development service
   public static host = 'http://10.50.100.198:4040/';    // UAT service
   public static host = 'http://10.50.100.198:4444/';    // production service
   public static host = 'http://10.50.100.113:4040/'; // UAT service
   public static host = 'http://10.50.100.113:4444/';    // production service
   */
  /*
    end of connection configuration
    */

  constructor(public httpClient: HttpClient, public cs: CommonService) {}

  public post(
    service: string,
    data: any,
    onError: any,
    errorLabel?: string
  ): Observable<any> {
    this.cs.startLoading();
    return this.httpClient
      .post<any>(
        ConnectorService.host + service,
        data,
        ConnectorService.httpOptions
      )
      .pipe(
        timeout(ConnectorService.timeOut),
        retry(ConnectorService.retryTimes),
        tap(
          res => this.handleResponse(res, onError, errorLabel),
          error => this.handleError(error, onError, errorLabel)
        )
      );
  }

  public postNoLoad(service: string, data: any, onError: any): Observable<any> {
    return this.httpClient
      .post<any>(
        ConnectorService.host + service,
        data,
        ConnectorService.httpOptions
      )
      .pipe(
        retry(ConnectorService.retryTimes),
        tap(() => {}, () => {})
      );
  }

  // absolute url connection
  public postToken(
    service: string,
    data: any,
    onError: any,
    errorLabel?: string
  ): Observable<any> {
    this.cs.startLoading();
    return this.httpClient
      .post<any>(service, data, ConnectorService.httpOptions)
      .pipe(
        timeout(ConnectorService.timeOut),
        retry(ConnectorService.retryTimes),
        tap(
          res => this.handleResponse(res, onError, errorLabel),
          error => this.handleError(error, onError, errorLabel)
        )
      );
  }

  public get(
    service: string,
    data: any,
    onError: any,
    errorLabel?: string
  ): Observable<any> {
    this.cs.startLoading();
    return this.httpClient.get(service, ConnectorService.httpOptions).pipe(
      timeout(ConnectorService.timeOut),
      retry(ConnectorService.retryTimes),
      tap(
        res => this.handleResponse(res, onError, errorLabel),
        error => this.handleError(error, onError, errorLabel)
      )
    );
  }
  /*
    load local json data and convert it to corresponding model
    resourceURL such as 'assets/config.json'
    */
  public getLocalResrouce(resourceURL: string): Observable<any> {
    return this.httpClient.get(resourceURL);
  }

  /*
    public validResponse(result: Response): boolean {
        // error type == 2 means you have error
        if (result.MessageStatus === 1) {
            return true;
        } else if (result.MessageStatus === 2) {
            return this.cs.hasData(result['SameClinicApptList']);
        }
        return false;
    }
    */

  public handleError(error: any, onError: any, errorLabel: string) {
    this.cs.stopLoading();
    if (error instanceof TimeoutError) {
      this.cs.showConnectionTimeout(onError, errorLabel);
    } else {
      this.cs.showConnectionErrorDialog(onError, errorLabel);
    }
  }

  public handleResponse(result: Response, onError: any, errorLabel: string) {
    this.cs.stopLoading();
    if (!this.cs.validResponse(result)) {
      // not authorized
      console.log(result.MessageStatus);
      console.log("erroe");
      if (result.IsAuthenticated == false) {
        this.cs.presentAcceptDialog(result.ErrorEndUserMessage, () => {
          this.cs.sharedService.clearAll();
          this.cs.openLogin();
        });
        return false;
      } else if (result.ErrorType === 2 || result.ErrorType === 4) {
        //console.log("error expired");
      } else {
        this.cs.showErrorMessageDialog(
          onError,
          errorLabel,
          result.ErrorEndUserMessage
        );
      }
    }
  }

  public getURLText(
    url: string,
    onError: any,
    errorLabel?: string
  ): Observable<any> {
    this.cs.startLoading();
    return this.httpClient.get(url).pipe(
      timeout(ConnectorService.timeOut),
      retry(ConnectorService.retryTimes),
      tap(
        res => {
          this.cs.stopLoading();
          if (!res) {
            this.cs.showConnectionErrorDialog(onError, errorLabel);
          }
        },
        error => this.handleError(error, onError, errorLabel)
      )
    );
  }
}
