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

const INTERVAL = 20; // 1s

let E = null;
function initEffects() {
  if (E) return;
  E = {
    poison: EffectTypes.get("minecraft:poison"),
    nausea: EffectTypes.get("minecraft:nausea"),
    wither: EffectTypes.get("minecraft:wither"),
    miningFatigue: EffectTypes.get("minecraft:mining_fatigue"),
    weakness: EffectTypes.get("minecraft:weakness"),
    slowness: EffectTypes.get("minecraft:slowness"),
  };
}

function getEq(player) {
  return player.getComponent("minecraft:equippable");
}
function idOf(itemStack) {
  return itemStack?.typeId ?? null;
}

function runAs(player, cmd) {
  try {
    player.runCommand(cmd); // SYNC
  } catch {}
}

function anyPlayerHasTag(tag) {
  for (const p of world.getAllPlayers()) {
    if (p.hasTag(tag)) return true;
  }
  return false;
}

function firstPlayerWithTag(tag) {
  for (const p of world.getAllPlayers()) {
    if (p.hasTag(tag)) return p;
  }
  return null;
}

function firstAnyPlayer() {
  const all = world.getAllPlayers();
  return all.length ? all[0] : null;
}

function cemeteryPoisonSwap(player) {
  if (!player.hasTag("cursedcementery")) return;

  const eq = getEq(player);
  if (!eq) return;

  const mh = eq.getEquipment(EquipmentSlot.Mainhand);
  if (idOf(mh) !== "dungeon:poison") return;

  try {
    eq.setEquipment(EquipmentSlot.Mainhand, new ItemStack("dungeon:old_piece", 1));
  } catch {
    runAs(
      player,
      "replaceitem entity @s slot.weapon.mainhand 0 dungeon:old_piece 1"
    );
  }
}

function cemeteryCraftingTablesTick() {
  const hasCursed = anyPlayerHasTag("cursedcementery");

  if (hasCursed) {
    const anchor = firstPlayerWithTag("cursedcementery");
    if (!anchor) return;
    runAs(
      anchor,
      "fill ~4 ~4 ~4 ~-4 ~-4 ~-4 dungeon:cemetery_crafting_table replace crafting_table"
    );
  } else {
    const anchor = firstAnyPlayer();
    if (!anchor) return;
    runAs(
      anchor,
      "fill ~4 ~4 ~4 ~-4 ~-4 ~-4 crafting_table replace dungeon:cemetery_crafting_table"
    );
  }
}

function punisherTick(player) {
  if (!player.hasTag("punisher")) return;

  // si NO hay nocturnal_shade cerca, matar los punishment lejos
  runAs(player, "execute unless entity @e[type=dungeon:nocturnal_shade,r=16] run kill @e[tag=punishment,type=dungeon:nocturnal_shade,r=128]");

  // marcar punishment a los nocturnal_shade con cemetery_test cerca
  runAs(player, "tag @e[type=dungeon:nocturnal_shade,tag=cemetery_test,r=32] add punishment");
}

// --- 4) REDPIE: scoreboard y buffs a monsters cerca (comandos)
function redpieTick(player) {
  if (!player.hasTag("redpie")) return;

  runAs(player, "scoreboard players remove @s redpie 1");
  runAs(player, "effect @e[family=monster,r=8] speed 1 2 false");
  runAs(player, "effect @e[family=monster,r=8] strength 1 1 false");
  runAs(player, "effect @e[family=monster,r=8] resistance 1 0 false");
}

function immunitiesTick(player) {
  if (!E) return;

  if (player.hasTag("poison_inmunity")) {
    if (player.getEffect(E.poison)) player.removeEffect(E.poison);
    if (player.getEffect(E.nausea)) player.removeEffect(E.nausea);
  }
  if (player.hasTag("wither_inmunity")) {
    if (player.getEffect(E.wither)) player.removeEffect(E.wither);
  }
  if (player.hasTag("fatigueinmunity")) {
    if (player.getEffect(E.miningFatigue)) player.removeEffect(E.miningFatigue);
  }
  if (player.hasTag("weakness_inmunity")) {
    if (player.getEffect(E.weakness)) player.removeEffect(E.weakness);
  }
  if (player.hasTag("slowness_inmunity")) {
    if (player.getEffect(E.slowness)) player.removeEffect(E.slowness);
  }

  // (m=1 = creative)
  try {
    if (player.getGameMode && player.getGameMode() === "Creative") {
      if (player.hasTag("punishment")) player.removeTag("punishment");
      if (player.hasTag("cemetery")) player.removeTag("cemetery");
    }
  } catch {
    runAs(player, "execute if entity @s[m=1] run tag @s remove punishment");
    runAs(player, "execute if entity @s[m=1] run tag @s remove cemetery");
  }
}

system.beforeEvents.startup.subscribe(() => {
  system.run(() => {
    initEffects();

    system.runInterval(() => {
      // 1) fill swap de crafting tables (1 vez por segundo)
      cemeteryCraftingTablesTick();

      // 2) lógica por jugador
      for (const p of world.getAllPlayers()) {
        cemeteryPoisonSwap(p);
        punisherTick(p);
        redpieTick(p);
        immunitiesTick(p);
      }
    }, INTERVAL);
  });
});
