import { Injectable } from '@angular/core';
import { NbDialogService } from '@nebular/theme';
import { first } from 'rxjs/operators';
import { MD2HeroInfo } from '../../games/massive-darkness2/massive-darkness2.model';
import { FileService } from '../file.service';
import { GameRoomService } from '../game-room.service';
import { LoginUserService } from '../login-user.service';
import { SignalRService, SignalRSession, SignalRMessage } from '../signal-r.service';
import { MD2StateService } from './md2-state.service';

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

  constructor(
    public fileService: FileService,
    private gameRoomService: GameRoomService,
    private loginUserService: LoginUserService,
    public stateService: MD2StateService,
    public signalRService: SignalRService,
    public dlgService: NbDialogService
  ) { }

  public get playerHero(): MD2HeroInfo {
    return this.stateService.playerHero;
  }
  public broadcastAllHeroInfoToAll() {
    this.stateService.info.heros.forEach(element => {
      this.broadcastHeroInfoToAll(element);
    });
    this.broadcastMobsInfo();
  }

  public broadcastHeroAction(action: string, extraValue: any = null) {
    let parameters = {};
    parameters['tabId'] = this.loginUserService.sessionTabId;
    parameters['extraValue'] = JSON.stringify(extraValue);
    this.broadcastMessage('heroAction', action, parameters);
  }

  public broadcastHeroInfoToAll(hero: MD2HeroInfo) {
    let message = {
      receiver: { isGroup: true, sessionId: this.gameRoomService.gameRoomId } as SignalRSession,
      from: { isGroup: false, sessionId: hero.playerInfo.signalRClientId },
      actionType: 'hero',
      actionName: 'update',
    } as SignalRMessage;
    message.parameters = { hero: JSON.stringify(hero) };
    this.gameRoomService.sendMessage(message).pipe(first()).subscribe(result => {
    });
  }

  public broadcastHeroInfoToOwner(hero: MD2HeroInfo) {
    let message = {
      receiver: { isGroup: false, sessionId: hero.playerInfo.signalRClientId } as SignalRSession,
      from: { isGroup: true, sessionId: this.gameRoomService.gameRoomId },
      actionType: 'hero',
      actionName: 'updateMyHero',
    } as SignalRMessage;
    message.parameters = { hero: JSON.stringify(hero) };
    this.gameRoomService.sendMessage(message).pipe(first()).subscribe(result => {
    });
  }

  /**
   * `sessionId` = null means broadcast to all
   */
  public broadcastMessage(actionType: string,
    actionName: string,
    parameters: { [key: string]: string; } = {},
    sessionId: string = null) {
    let message = {
      receiver: { isGroup: !sessionId, sessionId: sessionId } as SignalRSession,
      from: { isGroup: false, sessionId: this.loginUserService.userAccess.signalRSessionId },
      actionType: actionType,
      actionName: actionName,
      parameters: parameters
    } as SignalRMessage;

    if (sessionId == null) {
      message.receiver = { isGroup: true, sessionId: this.gameRoomService.gameRoomId } as SignalRSession
    } else {
      message.receiver = { isGroup: false, sessionId: this.gameRoomService.gameRoomId } as SignalRSession
    }
    this.gameRoomService.sendMessage(message).pipe(first()).subscribe(result => {
    });
  }
  public broadcastGameInfo() {
    let parameters = {};
    parameters['gameInfo'] = JSON.stringify(this.stateService.info);
    this.broadcastMessage('GameRoom', 'update', parameters);
  }
  public broadcastRoundPhase() {
    let parameters = {};
    parameters['phase'] = JSON.stringify(this.stateService.info.roundPhase);
    this.broadcastMessage('GameRoom', 'phase', parameters);
  }

  public broadcastMobsInfo() {
    let parameters = {};
    parameters['roamingMonsters'] = JSON.stringify(this.stateService.info.roamingMonsters);
    parameters['mobs'] = JSON.stringify(this.stateService.info.mobs);
    this.broadcastMessage('mobs', 'update', parameters);
  }

  public broadcastMyHeroInfo() {
    this.broadcastHeroInfoToAll(this.playerHero);
  }
}
