import { world, system } from "@minecraft/server";

import { Network } from "./Network/Network";
import { BitmaskMapUtils, BitmaskMap, BitmaskSettings, BitmaskLocations } from "./Network/MCCommAPI";

world.afterEvents.worldLoad.subscribe(() => {
  for (let player of world.getPlayers()) {
    player.speakingTimer = 0;
  }
})
/*
talk
listen
prox

1
normal player, not connected to radio
> talk, listen, prox, turn off 2, turn off 3

dead player for 1
> no talk, listen, prox, turn off 2, turn off 3

2
normal player connected to radio
> listen 2, no prox 2, turn off 3

3
dead player (1 & 3 active)
> talk, listen, no prox
*/

//B1 is normal speaking, B2 is radio, B3 is among spectators

//Player alive, B1 active default
const def = BitmaskMapUtils.Default;

//Player on radio, keep B1 on default, turn on B2 listen, disable Prox in B2
const radioListen =
  BitmaskMapUtils.Default |
  BitmaskMap.ListenBitmask2 |
  (BitmaskSettings.ProximityDisabled << BitmaskLocations.Bitmask2Settings);

//Player on radio, keep B1 on default, turn on B2 listen, turn on B2 talk, disable Prox in B2
const radioSpeak =
  BitmaskMapUtils.Default |
  BitmaskMap.ListenBitmask2 |
  BitmaskMap.TalkBitmask2 |
  (BitmaskSettings.ProximityDisabled << BitmaskLocations.Bitmask2Settings);

//Player is dead, turn on B1 listen, turn on B3 listen, turn on B3 talk, Disable Prox and VoiceEffects in B3.
const dead =
  BitmaskMap.ListenBitmask1 |
  BitmaskMap.ListenBitmask3 |
  BitmaskMap.TalkBitmask3 |
  ((BitmaskSettings.ProximityDisabled | BitmaskSettings.VoiceEffectsDisabled) << BitmaskLocations.Bitmask3Settings);

class LethalCompany {
  static SpeakingPlayers = [];

  constructor(network) {
    /** @type { Network } **/
    this.Network = network;

    let connected = [];
    system.runInterval(async () => {
      if (!this.Network.IsConnected) return;
      connected = await this.Network.GetParticipants();
    }, 20);

    system.runInterval(() => {
      if (!this.Network.IsConnected) return;
      for (let player of world.getPlayers()) {
        if (!connected.includes(player.id)) continue;

        if (player.speakingTimer > 0) {
          player.speakingTimer--;
        }
        //world.sendMessage(`${player.speakingTimer}`)

        if (player.hasTag("spectator")) {
          try {
            this.setPlayerDead(player);
          } catch {}
        }

        if (!player.hasTag("spectator")) {
          const radioState = player.getProperty("js:walkie_state");

          if (radioState == 0) {
            try {
              this.setPlayerDefault(player);
            } catch {}
          } else if (radioState == 1) {
            try {
              this.setPlayerRadioListen(player);
            } catch {}
          } else if (radioState == 2) {
            try {
              this.setPlayerRadioSpeak(player);
            } catch {}
          }
        }
      }
    });
  }

  setPlayerDefault(player) {
    this.Network.SetPlayerBitmask(player, def);
  }
  setPlayerRadioListen(player) {
    this.Network.SetPlayerBitmask(player, radioListen);
  }
  setPlayerRadioSpeak(player) {
    this.Network.SetPlayerBitmask(player, radioSpeak);
  }
  setPlayerDead(player) {
    this.Network.SetPlayerBitmask(player, dead);
  }
}

system.runInterval(() => {
  //console.warn(LethalCompany.SpeakingPlayers)

  if (LethalCompany.SpeakingPlayers.length > 0) {
    for (let speaker of LethalCompany.SpeakingPlayers) {
      let player;
      for (let playerInstance of world.getPlayers()) {
        if (speaker == playerInstance.id) {
          player = playerInstance;
          console.warn(speaker);
        }
      }
      if (!player.hasTag("spectator")) {
        //  world.sendMessage(`${player.nameTag} is speaking`)
        player.runCommand(`scriptevent js:broadcastNoise talk`);
      }
    }
  }
}, 20);

export { LethalCompany };
