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

/* MÓDULOS DE ARRANQUE */
import "./dungeonbadlucktest.js";
import "./dungeonitems.js";
import "./dungeonspider_boss.js"
import "./dungeonguide.js";
import "./dungeontools_blocks.js";
import { regeneration } from "./dungeonsaturation.js";
import "./dungeonblocks.js";
import "./dungeonSkeletons.js";
import "./dungeonlight.js";

import { toolseffects } from "./dungeoncombat.js";
import "./dungeonaimobs.js";
import { equipMobWithGearDetails, getDifficultyMultiplier, getCachedGear } from "./dungeonDifficulty.js";
import { item_lore_event } from "./dungeonlore.js";
import { detectBlocks } from "./dungeontomb.js";
import { executeDeathCommands, moonstone, controller_player } from "./dungeonplayer_functions.js";
import { isLookingAtHead } from "./dungeongorgona_function.js";
import { info, detectDungeonBlocks } from "./dungeonfunctions.js";
import { cave_event } from "./dungeoncave_event.js";
import { registerBlockComponents } from "./dungeoncore.js";
import { initialize } from "./dungeonalive.js";
import "./dungeonalive.js";
import { detectCloudBlocks } from "./dungeoncloudblock.js";
import fear_ui from "./fear_ui.js";

import { specialarmors } from "./armor_set_bonus.js";
import { cobalt_armor } from "./armors/cobalt.js";
import { tungsten_armor } from "./armors/tungsten.js";
import { jade_armor } from "./armors/jade.js";
import "./armors/glimmerite.js";
import "./armors/viritum.js";
import "./armors/ancient.js";
import "./dungeondifficulty_config.js";

specialarmors([cobalt_armor, tungsten_armor, jade_armor]);

const INTERVALS = {
  UI: 21,
  CORE: 4,
  controller: 0.5,
  DETECT_BLOCKS: 21,
  INFO: 2,
  REMOVE_VIEW_TAG: 50
};

const BATCH = 2;

let globalTick = 0;
let playerQueue = [];
let pointer = 0;
const perPlayer = new Map();
const regenDelay = new Map();
let ui_index = 0;

/* UI rotativa */
system.runInterval(() => {
  let players = [];
  try { players = world.getPlayers(); } catch { }

  if (players.length === 0) return;

  if (ui_index >= players.length) ui_index = 0;

  try { fear_ui(players[ui_index]); } catch { }
  ui_index++;
}, INTERVALS.UI);

/* Inicialización y controladores */
system.runInterval(() => {
  let players = [];
  try { players = world.getPlayers(); } catch { }

  if (players.length === 0) return;

  for (const p of players) {
    try {
      initialize(p);
    } catch { }
    try {
      executeDeathCommands(p);
    } catch { }
    try {
      controller_player(p);
    } catch { }
  }
}, INTERVALS.controller);

/* Efectos de combate */
world.afterEvents.entityHurt.subscribe(({ damageSource, hurtEntity }) => {
  const attacker = damageSource.damagingEntity;
  if (attacker?.typeId === "minecraft:player") {
    try { toolseffects(attacker, hurtEntity); } catch { }
  }
});

/* Reseteo de tags al reaparecer */
world.afterEvents.playerSpawn.subscribe(({ player }) => {
  try { player.removeTag("cursedcementery"); } catch { }
  try { player.removeTag("invulnerable"); } catch { }
  try { player.removeTag("cave_fog_active"); } catch { }
  try { player.runCommand("scoreboard players set @s tombstest 0"); } catch { }
  try { player.runCommand("fog @s remove cemetery"); } catch { }
  try { player.runCommand("fog @s remove dcave_fog"); } catch { }
});

/* Jugadores cercanos */
function getNearbyPlayers(entity, maxDistance = 96) {
  const maxSq = maxDistance * maxDistance;
  let players = [];
  try { players = world.getPlayers(); } catch { }
  return players.filter(player => {
    try {
      const dx = player.location.x - entity.location.x;
      const dy = player.location.y - entity.location.y;
      const dz = player.location.z - entity.location.z;
      return dx * dx + dy * dy + dz * dz <= maxSq;
    } catch {
      return false;
    }
  });
}

/* Equipar mobs dinámicos */
world.afterEvents.entitySpawn.subscribe(({ entity }) => {
  try {
    if (!entity || entity.hasTag("__equipped")) return;
  } catch { }

  const validTypes = new Set([
    "dungeon:dungeonzombie", "dungeon:beach_skeleton", "dungeon:lush_skeleton",
    "dungeon:miner_skeleton", "dungeon:gray_mummy", "dungeon:purple_mummy", "dungeon:skeleton",
    "dungeon:frozen_stray", "dungeon:scorched_stray"
  ]);
  if (!validTypes.has(entity.typeId)) return;

  const players = getNearbyPlayers(entity);
  if (players.length === 0) return;

  let bestGear = null;
  let bestScore = -Infinity;
  let multiplier = 1;

  try { multiplier = getDifficultyMultiplier(); } catch { }

  for (const player of players) {
    try {
      const gear = getCachedGear(player);
      if (gear && gear.totalScore > bestScore) {
        bestGear = gear;
        bestScore = gear.totalScore;
      }
    } catch { }
  }

  if (!bestGear) return;

  try {
    equipMobWithGearDetails(entity, {
      helmet: bestGear.helmet * multiplier,
      chestplate: bestGear.chestplate * multiplier,
      leggings: bestGear.leggings * multiplier,
      boots: bestGear.boots * multiplier,
      weapon: bestGear.weapon * multiplier,
      totalScore: bestGear.totalScore * multiplier
    });
    entity.addTag("__equipped");
  } catch { }
});

/* Tick centralizado */
system.runInterval(() => {
  let players = [];
  try { players = world.getPlayers(); } catch { }

  if (globalTick % 20 === 0) {
    playerQueue = [...players];
    pointer = 0;
    const ids = new Set(players.map(p => p.id));
    for (const key of perPlayer.keys()) if (!ids.has(key)) perPlayer.delete(key);
    for (const key of regenDelay.keys()) if (!ids.has(key)) regenDelay.delete(key);
  }

  for (const p of players) {
    try { isLookingAtHead(p); } catch { }
  }

  for (let i = 0; i < BATCH && pointer < playerQueue.length; i++, pointer++) {
    const p = playerQueue[pointer];

    try {
      const tickRecord = regenDelay.get(p.id) ?? 0;

      if (globalTick - tickRecord >= 7) {
        try { regeneration(p); } catch { }
        regenDelay.set(p.id, globalTick);
      }

      try { moonstone(p); } catch { }
      try { detectCloudBlocks(p); } catch { }

      let bag = perPlayer.get(p.id) ?? { info: 0, detect: 0, view: 0 };
      bag.info++;
      bag.detect++;
      bag.view++;

      if (bag.info >= INTERVALS.INFO) {
        try {
          if (p.hasTag("spectral_amulet") && !p.hasTag("luck_info") ) {
            info(p);
            detectDungeonBlocks(p);
          }
        } catch { }
        bag.info = 0;
      }

      if (bag.detect >= INTERVALS.DETECT_BLOCKS) {
        try {
          cave_event(p);
          item_lore_event(p);
          detectBlocks(p);
        } catch { }
        bag.detect = 0;
      }

      if (bag.view >= INTERVALS.REMOVE_VIEW_TAG) {
        try {
          if (p.hasTag("luck_info")) p.removeTag("luck_info");
        } catch { }
        bag.view = 0;
      }

      perPlayer.set(p.id, bag);
    } catch { }
  }

  if (pointer >= playerQueue.length) pointer = 0;
  globalTick++;
}, INTERVALS.CORE);

/* Registro de componentes */
system.beforeEvents.startup.subscribe(({ blockComponentRegistry }) => {
  try { registerBlockComponents(blockComponentRegistry); } catch { }
});
