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

const regenerationTick = new Map();
const REGENERATION_INTERVAL = 21;

export function moonstone(player) {
  const tod = world.getTimeOfDay();
  if (
    tod >= 12500 && tod <= 24000 &&
    player.hasTag("moonstone_item")
  ) {
    // Efectos constantes
    player.runCommand('effect @s speed 3 1 true');
    player.runCommand('effect @s strength 3 1 true');
    player.runCommand('effect @s jump_boost 3 1 true');
    player.runCommand('effect @s hunger 3 25 true');

    // Regeneración
    let tick = (regenerationTick.get(player.id) ?? 0) + 1;
    if (tick >= REGENERATION_INTERVAL) {
      if (Math.random() < 0.2) {
        player.runCommand('effect @s regeneration 5 0 true');
      }
      tick = 0;
    }
    regenerationTick.set(player.id, tick);
  } else {
    regenerationTick.delete(player.id);
  }
}

world.afterEvents.playerSpawn.subscribe(({ player }) => {
  if (player.location.y < -64 || player.location.y > 319) return;

  const controllers = player.dimension.getEntities({
    type: "dungeon:player_controller",
    location: player.location
  });

  for (const entity of controllers) {
    const tags = entity.getTags();
    if (!tags.some(tag => tag === "snow" || tag === "snow2" || tag === "sandstorm")) {
      entity.remove();
    }
  }
});

export function controller_player() {
  const validTags = new Set(["snow", "snow2", "sandstorm"]);
  const players = world.getPlayers();

  // Map dimensión → controladores usados
  const usedControllersByDimension = new Map();

  for (const player of players) {
    const dimension = player.dimension;

    if (!usedControllersByDimension.has(dimension.id)) {
      usedControllersByDimension.set(dimension.id, new Set());
    }

    const usedControllers = usedControllersByDimension.get(dimension.id);
    const { x, y, z } = player.location;

    const controllers = dimension.getEntities({
      type: "dungeon:player_controller",
      location: player.location,
      maxDistance: 4,
    });

    let assignedController = null;

    for (const controller of controllers) {
      const tags = controller.getTags();
      const hasValidTag = tags.some(t => validTags.has(t));

      if (!hasValidTag) {
        controller.remove();
        continue;
      }

      if (tags.includes(player.id)) {
        assignedController = controller;
        usedControllers.add(controller.id);
      }
    }

    if (!assignedController) {
      const c = dimension.spawnEntity(
        "dungeon:player_controller",
        { x, y: y + 0.9, z }
      );
      c.addTag(player.id);
      usedControllers.add(c.id);
    } else {
      const head = player.getHeadLocation();
      assignedController.teleport({
        x: head.x,
        y: head.y + 0.9,
        z: head.z
      });

      if (assignedController.hasTag("snow")) {
        assignedController.removeTag("snow2");
        assignedController.removeTag("sandstorm");
      } else if (assignedController.hasTag("snow2")) {
        assignedController.removeTag("snow");
        assignedController.removeTag("sandstorm");
      } else if (assignedController.hasTag("sandstorm")) {
        assignedController.removeTag("snow");
        assignedController.removeTag("snow2");
      }
    }
  }

  // Limpieza segura por dimensión real
  for (const player of players) {
    const dimension = player.dimension;
    const used = usedControllersByDimension.get(dimension.id);

    for (const controller of dimension.getEntities({
      type: "dungeon:player_controller"
    })) {
      if (!used?.has(controller.id)) {
        controller.remove();
      }
    }
  }
}


let isSubscribed = false;

function onPlayerDeath({ deadEntity }) {
  if (!(deadEntity instanceof Player)) return;

  const loc = deadEntity.location;
  const rounded = `X: ${Math.round(loc.x)}, Y: ${Math.round(loc.y)}, Z: ${Math.round(loc.z)}`;

  const commands = [
    `tag @s[tag=!guide_book] add guide_book`,
    `tag @s remove respawned`,
    `fog @s remove cemetery`,
    `fog @s remove cursedcementery`,
    `clear @s[tag=totemofrecovery] dungeon:totemofrecovery 0 1`,
    `execute if entity @s[tag=totemofrecovery] run summon dungeon:gravestone`,
    `execute if entity @s[tag=totemofrecovery] run msg @s §3${rounded}`,
    `execute if entity @s[tag=totemofrecovery] run kill @e[type=item,name="Totem of recovery §3(Accessory) ",c=1,r=6]`,
    `execute if entity @s[tag=totemofrecovery] run kill @e[type=item,name="Totem de la recuperación §3(Accesorio) ",c=1,r=6]`,
    `execute if entity @s[tag=totemofrecovery] run playsound random.totem @s`,
    `execute if entity @s[tag=totemofrecovery] run particle minecraft:totem_particle ~ ~1~`,
    `xp -99l @s`,
    `tag @s add invulnerable`,
    `scoreboard players reset @s stonetest`,
    `scoreboard players remove @s[m=0,scores={insomnio=45000..}] insomnio 10000`,
    `tag @s remove cemetery`,
    `tag @s remove punisher`,
    `tag @s remove punishment`,
    `tag @s remove stone_player`,
    `tag @s remove stone`,
    `function no_light`
  ];

  for (const cmd of commands) {
    try {
      deadEntity.runCommand(cmd);
    } catch { }
  }
}

export function executeDeathCommands() {
  if (isSubscribed) return;
  world.afterEvents.entityDie.subscribe(onPlayerDeath);
  isSubscribed = true;
}
