import { Music } from "../Classes";
import { world, overworld, afterEvents } from "../Constants";
import { onPlayerLoad, runInterval, runTimeout } from "../Utils";

runInterval(() => {
  overworld.commandRunAsync(
    `tag @a add background`,
    `tag @a remove fight`,
    `execute as @p if entity @e[type=eternal:golden_dragon] run tag @a[x=49112,y=112,z=-199,dx=-78,dy=27,dz=42,tag=!golden_dragon] add fight`,
    `execute as @p if entity @e[type=eternal:mystical_golem] run tag @a[x=50046,y=125,z=522,dx=-30,dy=11,dz=-32] add fight`,
    `execute as @p if entity @e[type=eternal:yeti] run tag @a[x=49843,y=113,z=-1040,dx=-53,dy=34,dz=-62] add fight`,
    `tag @a[tag=teleporting] remove background `,
    `tag @a[tag=in_cutscene] remove background `
  );
});

const musicTrack = [
  new Music("music.background", "background", 33),
  new Music("music.fight", "fight", 36),
  new Music("music.intro", "intro", 50),
];

afterEvents.playerSpawn.subscribe((e) => {
  const { player } = e;

  runTimeout(() => {
    for (const music of musicTrack) {
      player.removeTag(music.tag);
    }
  }, 20);
});

function getCurrentMusic(player) {
  for (let i = musicTrack.length - 1; i >= 0; i--) {
    if (player.hasTag(musicTrack[i].tag)) {
      return musicTrack[i];
    }
  }
  return null;
}

onPlayerLoad((player) => {
  try {
    const checkMovement = runInterval(() => {
      const { x, y, z } = player?.getVelocity();
      if (x !== 0 || y !== 0 || z !== 0) {
        const currentMusic = getCurrentMusic(player);
        if (currentMusic) {
          player.removeTag(`playing_${currentMusic.tag}`);
          checkMovement.dispose();
        }
      }
    });
  } catch (error) {}
});

function stopAllMusic(player) {
  for (const music of musicTrack) {
    player.commandRunAsync(`stopsound @s ${music.track}`);
  }
  musicTrack.forEach((music) => {
    player.removeTag(`playing_${music.tag}`);
  });
}

function playMusic(player, music) {
  player.commandRunAsync(`playsound ${music.track}`);
  player.addTag(`playing_${music.tag}`);

  const stopMusicTimeout = runTimeout(() => {
    player.removeTag(`playing_${music.tag}`);
  }, music.durationTick);

  try {
    const checkTagInterval = runInterval(() => {
      if (!player?.hasTag(music.tag)) {
        player.removeTag(`playing_${music.tag}`);
        player.commandRunAsync(`stopsound @s ${music.track}`);
        stopMusicTimeout.dispose();
        checkTagInterval.dispose();
      }
    });
  } catch (error) {}
}

const initialPlayers = world.getAllPlayers();
initialPlayers.forEach((player) => {
  stopAllMusic(player);
});

runInterval(() => {
  const players = world.getAllPlayers();

  players.forEach((player) => {
    const currentMusic = getCurrentMusic(player);

    if (currentMusic && !player.hasTag(`playing_${currentMusic.tag}`)) {
      stopAllMusic(player);
      playMusic(player, currentMusic);
    }
  });
});
