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

const SCOREBOARD_OBJECTIVE = "otherworldly_difficulty";
const SCOREBOARD_FAKE_PLAYER = "difficulty";

let lastDifficultyScore = -1;
let dimensionsCache = null;

function getAllDimensions() {
  if (dimensionsCache) return dimensionsCache;

  dimensionsCache = [
    world.getDimension("overworld"),
    world.getDimension("nether"),
    world.getDimension("the_end"),
  ];

  return dimensionsCache;
}

function setDifficultyScore(value) {
  if (value === lastDifficultyScore) return;
  lastDifficultyScore = value;

  const player = world.getPlayers()[0];
  if (!player) return;

  player.runCommand(
    `scoreboard players set ${SCOREBOARD_FAKE_PLAYER} ${SCOREBOARD_OBJECTIVE} ${value}`
  );
}

//function giveHardcoreItem(player) {
  //if (player.hasTag("received_hardcore_book")) return;

  //player.runCommand("give @s dungeon:guide_book");
//  player.runCommand("give @s dungeon:vampiric_amulet");
  //player.addTag("received_hardcore_book");
  //player.addTag("fear_info");
//}

function clearExpertAura(players) {
  for (const player of players) {
    if (player.hasTag("player_expert")) player.removeTag("player_expert");
  }

  for (const dim of getAllDimensions()) {
    for (const mob of dim.getEntities({ families: ["monster"] })) {
      if (mob.hasTag("otherworldly_expert")) mob.removeTag("otherworldly_expert");
    }
  }
}

function applyExpertAura(expertPlayers) {
  if (expertPlayers.length === 0) return;

  for (const player of expertPlayers) {
    const mobs = player.dimension.getEntities({
      location: player.location,
      maxDistance: 94,
      families: ["monster"],
    });

    for (const mob of mobs) {
      if (!mob.hasTag("otherworldly_expert")) mob.addTag("otherworldly_expert");
    }
  }
}

function updateDifficulty() {
  const players = world.getPlayers();
  if (players.length === 0) return;

  const isHardcore = world.isHardcore;
  const difficulty = world.getDifficulty();

  const expertPlayers = [];
  for (const p of players) if (p.hasTag("player_expert")) expertPlayers.push(p);

  if (isHardcore) {
    setDifficultyScore(3);
    applyExpertAura(expertPlayers.length ? expertPlayers : players);

   // for (const player of players) {
     // if (!player.hasTag("player_expert")) player.addTag("player_expert");
      //giveHardcoreItem(player);
   // }
    return;
  }

  if (difficulty === Difficulty.Hard) {
    if (expertPlayers.length > 0) {
      setDifficultyScore(3);
      applyExpertAura(expertPlayers);
    } else {
      clearExpertAura(players);
      setDifficultyScore(2);
    }
    return;
  }

  if (difficulty === Difficulty.Normal) {
    clearExpertAura(players);
    setDifficultyScore(1);
    return;
  }

  clearExpertAura(players);
  setDifficultyScore(0);
}

system.runInterval(updateDifficulty, 20);
