import { Injectable } from '@angular/core';
import * as signalR from "@microsoft/signalr"
import { Subject } from 'rxjs';
import { environment } from '../../environments/environment';
import { AvalonStage, GameInfo, Player, PlayerAction, Role } from '../entity/Avalon';
import { UuidUtils } from '../utilities/uuid-utils';
import { SessionService } from './session.service';


const minimumPlayers = 5;
const maximumPlayers = 10;
const players_good: number[] = [3, 4, 4, 5, 6, 6];
const players_evil: number[] = [2, 2, 3, 3, 3, 4];

//const SIGNAL_R_URL = (id: string = null) => { return `${environment.apiUrl}/${id}Hub` }
const SIGNAL_R_URL = (id: string = null) => { return `${environment.signalRUrl}/${id}Hub` }
@Injectable({
  providedIn: 'root'
})
export class AvalonService {
  data: GameInfo;
  rngAssignRole: boolean = false;

  public get connectionId(): string {
    return this.hubConnection.connectionId;
  }

  public get id(): string {
    let _id = localStorage.getItem('avalonId');
    if (!_id) {
      _id = UuidUtils.generate();
      this.id = _id;
    };
    return _id;
  }
  public set id(v: string) {
    localStorage.setItem('avalonId', v);
  }

  private enableMordred: boolean = false;
  private enableOberon: boolean = false;
  //Morgana,Percival,Merlin 
  private hubConnection: signalR.HubConnection;
  broadcastFromAPI$ = new Subject<Player>();
  applyCdChange$ = new Subject<any>();
  refreshPlayers$ = new Subject<Player[]>();
  broadcastFromSignalR$ = new Subject<{ action: string, jsonString: string }>();

  isHost: boolean = false;;

  constructor(private session: SessionService) { }

  //#region  signalR

  public joinGame(username: string, seq: number) {
    this.session.currentUserName = username;
    //this.username = username;
    // this.hubConnection = new signalR.HubConnectionBuilder()
    //   .configureLogging(signalR.LogLevel.Debug)
    //   .withUrl(SIGNAL_R_URL('AvalonHub'))
    //   .withAutomaticReconnect()
    //   .build();
    this.hubConnection = new signalR.HubConnectionBuilder()
      //.configureLogging(signalR.LogLevel.Debug)
      .withUrl(SIGNAL_R_URL('Avalon') + `?username=${username}&userId=${this.id}`, {
        //skipNegotiation: true,
        //transport: signalR.HttpTransportType.WebSockets
      })
      .withAutomaticReconnect()
      .build();
    this.hubConnection.serverTimeoutInMilliseconds = 1000 * 60 * 10; // for  10 minute

    this.hubConnection.on("Broadcast", (action, jsonString) => {
      this.broadcastFromSignalR$.next({ action, jsonString });
      //this.applyCdChange$.next();
    });

    Object.defineProperty(WebSocket, 'OPEN', { value: 1, });
    this.hubConnection
      .start()
      .then(() => {
        console.log('AvalonHub Connection started:' + this.hubConnection.connectionId);
        try {
          //this.initSignalR();
          this.data.players = [{ connectionId: this.hubConnection.connectionId, username, id: this.id, seq } as Player];
          //this.broadcastMe('JoinGame');
          this.broadcastPlayer('JoinGame', this.data.players.find(p => p.id == this.id));
          this.applyCdChange$.next();
        } catch (err) {
          console.error(err);
        }
      })
      .catch(err => console.log('Error while starting connection: ', err));

  }

  broadcastPlayer(action: PlayerAction, player: Player) {
    console.log('broadcastPlayer', player);
    this.broadcast(action, player);

  }


  broadcast(action: PlayerAction, obj: any) {
    this.hubConnection.send("Broadcast", this.hubConnection.connectionId, action, JSON.stringify(obj));
  }

  //#endregion


}
