import * as signalR from '@microsoft/signalr';
import { EnvironmentConfigService } from '.';
import signalRStore from '../stores/signalR.store';
import { TokenService } from './token.service';
export class SignalRService {
  constructor() {
    console.log('Starting signalR');
    //TODO: update courseClassId
    var defaultCourseClassId = 1;
    var sparkleConfig = EnvironmentConfigService.getInstance().get('sparkle');
    this.connection = new signalR.HubConnectionBuilder()
      .withUrl(`${sparkleConfig.apiUrl}hubs/sparkle?url=${window.location.href}${defaultCourseClassId > 0 ? '&courseClassId=' + defaultCourseClassId : ''}`, {
      accessTokenFactory: () => this.getToken(),
      skipNegotiation: true,
      transport: signalR.HttpTransportType.WebSockets,
    })
      .configureLogging(signalR.LogLevel.Debug)
      //.withAutomaticReconnect()
      .withAutomaticReconnect({
      nextRetryDelayInMilliseconds: retryContext => {
        if (retryContext.elapsedMilliseconds < 60000) {
          // If we've been reconnecting for less than 60 seconds so far,
          // wait between 0 and 10 seconds before the next reconnect attempt.
          return Math.random() * 10000;
        }
        else {
          // If we've been reconnecting for more than 60 seconds so far, stop reconnecting.
          return null;
        }
      },
    })
      .build();
    this.connection.on('SendMessage', (user, data) => {
      let payload = JSON.parse(data);
      console.log('Server said ', user, payload);
    });
    this.connection.onclose(error => { });
    this.connection.onreconnecting(error => {
      console.assert(this.connection.state === signalR.HubConnectionState.Reconnecting);
    });
    this.connection.onreconnected(connectionId => {
      console.assert(this.connection.state === signalR.HubConnectionState.Connected);
    });
  }
  static getInstance() {
    if (!SignalRService.instance) {
      SignalRService.instance = new SignalRService();
    }
    return SignalRService.instance;
  }
  async start() {
    console.log('start');
    try {
      signalRStore.state.connecting = true;
      signalRStore.state.connected = !signalRStore.state.connecting;
      await this.connection.start();
      console.log(this.connection);
      signalRStore.state.connecting = false;
      signalRStore.state.connected = this.connection.state === signalR.HubConnectionState.Connected;
      console.assert(this.connection.state === signalR.HubConnectionState.Connected);
      console.log('SignalR Connected.');
    }
    catch (err) {
      console.assert(this.connection.state === signalR.HubConnectionState.Disconnected);
      console.log(err);
    }
  }
  async callSignalR(hub, data) {
    let token = await this.getToken();
    if (!token) {
      console.log('Cannot connect to signalR. Not logged in');
      return;
    }
    this.connection.invoke(hub, JSON.stringify(data));
  }
  getToken() {
    var token = TokenService.getInstance().getTokenSync();
    if (token) {
      return token;
    }
    return null;
  }
}
