import { Injectable } from '@angular/core';
import { IEventMessage } from '../models/event.message';
import { Subject, timer } from 'rxjs';
import { OAuthService } from 'angular-oauth2-oidc';
import { HubConnection, HubConnectionBuilder, LogLevel ,HttpTransportType,HubConnectionState} from '@microsoft/signalr';
import { AppConfig } from "../shared/app.config";


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

  public event:Subject <IEventMessage> = new Subject<IEventMessage>();
  private _connection: HubConnection = null;
  private _apiEndPoint: string;
  public authenticated = false;
    
  constructor(private oauthService: OAuthService, private appConfig: AppConfig) {
    this._apiEndPoint = appConfig.getConfig("apiEndPoint");
    this._connection = new HubConnectionBuilder().withUrl(`${ this._apiEndPoint}/eventHub`,
    { transport: HttpTransportType.WebSockets,
      // accessTokenFactory: () => {
      //   return oauthService.getAccessToken();
      // },
      skipNegotiation:true 
    }).withAutomaticReconnect().configureLogging(LogLevel.Information).build();
    this._connection.on('event', eventMessage => {
      this.event.next(eventMessage);
    });
    this._connection.onreconnected( event => {
      this.Authenticate();
    });
    this.Start();
  }

  Start() {
    if(this._connection&&!(this._connection.state === HubConnectionState.Connected || this._connection.state === HubConnectionState.Connecting))
    this._connection.start().then(() => {
      this.Authenticate();
    }); 
  }

  private Authenticate() {
    const accessToken = this.oauthService.getAccessToken();   
    if (this.oauthService.hasValidAccessToken()) {
      this._connection.send('authenticate', this.oauthService.getAccessToken());
      this.authenticated=true;
    } else {
      //try again after half a second
       setTimeout(() => {
         this.Authenticate();
       }, 800);
    }
  }

  Stop() {
    if(this._connection&&(this._connection.state === HubConnectionState.Connected || this._connection.state === HubConnectionState.Connecting)) {
      this._connection.stop();
    }
  }
} 
