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

const INTERVAL = 20;          // 1s
const RADIUS = 48;
const EFFECT_DUR = 420;       // 21s (equivale a /effect 20s con margen)
const PHASE_TAGS = ["difficulty_phase1", "difficulty_phase2", "difficulty_phase3", "difficulty_phase4"];

const PHASE_EFFECTS = {
  difficulty_phase1: { str: 0, res: 0 },
  difficulty_phase2: { str: 0, res: 0 },
  difficulty_phase3: { str: 1, res: 1 },
  difficulty_phase4: { str: 2, res: 1 },
};

let E = null;
function initEffects() {
  if (E) return;
  E = {
    strength: EffectTypes.get("minecraft:strength"),
    resistance: EffectTypes.get("minecraft:resistance"),
  };
}

function setTag(player, tag, enabled) {
  if (enabled) {
    if (!player.hasTag(tag)) player.addTag(tag);
  } else {
    if (player.hasTag(tag)) player.removeTag(tag);
  }
}

function dist2(a, b) {
  const dx = a.x - b.x;
  const dy = a.y - b.y;
  const dz = a.z - b.z;
  return dx * dx + dy * dy + dz * dz;
}

function highestPhaseNearPlayer(player, sourcesByPhase) {
  const ploc = player.location;
  const maxD2 = RADIUS * RADIUS;

  // prioridad 4 a 1
  for (let i = PHASE_TAGS.length - 1; i >= 0; i--) {
    const tag = PHASE_TAGS[i];
    const srcs = sourcesByPhase[tag];
    for (const s of srcs) {
      if (dist2(ploc, s.location) <= maxD2) return tag;
    }
  }
  return null;
}

const SKELETON_PHASE_TAG = {
  difficulty_phase1: "hard_phase1",
  difficulty_phase2: "hard_phase2",
  difficulty_phase3: "hard_phase3",
  difficulty_phase4: "hard_phase4",
};

const ALL_SKELETON_HARD_TAGS = ["hard_phase1", "hard_phase2", "hard_phase3", "hard_phase4"];

function applyMobBuffsFromSources(sourcesByPhase) {
  if (!E) return;

  for (const phaseTag of PHASE_TAGS) {
    const srcs = sourcesByPhase[phaseTag];
    if (!srcs.length) continue;

    const { str, res } = PHASE_EFFECTS[phaseTag];
    const skTag = SKELETON_PHASE_TAG[phaseTag];

    for (const s of srcs) {
      const dim = s.dimension;
      const loc = s.location;

      const monsters = dim.getEntities({
        location: loc,
        maxDistance: RADIUS,
        families: ["monster"],
      });

      for (const m of monsters) {
        if (E.strength) m.addEffect(E.strength, EFFECT_DUR, { amplifier: str, showParticles: false });
        if (E.resistance) m.addEffect(E.resistance, EFFECT_DUR, { amplifier: res, showParticles: false });
      }

      const skeletons = dim.getEntities({
        location: loc,
        maxDistance: RADIUS,
        families: ["skeleton"],
      });

      for (const sk of skeletons) {
        for (const t of ALL_SKELETON_HARD_TAGS) {
          if (t !== skTag && sk.hasTag(t)) sk.removeTag(t);
        }
        if (!sk.hasTag(skTag)) sk.addTag(skTag);
      }
    }
  }
}



function propagatePhaseTagsToPlayers(sourcesByPhase) {
  const players = world.getAllPlayers();

  for (const p of players) {
    const highest = highestPhaseNearPlayer(p, sourcesByPhase);

    if (!highest) {
      //limpieza:
      // for (const t of PHASE_TAGS) setTag(p, t, false);
      continue;
    }

    // Asegura solo la fase más alta
    for (const t of PHASE_TAGS) setTag(p, t, t === highest);
  }
}

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

    system.runInterval(() => {
      // recolecta fuentes (players con tag de fase)
      const sourcesByPhase = {
        difficulty_phase1: [],
        difficulty_phase2: [],
        difficulty_phase3: [],
        difficulty_phase4: [],
      };

      for (const p of world.getAllPlayers()) {
        for (const t of PHASE_TAGS) {
          if (p.hasTag(t)) sourcesByPhase[t].push(p);
        }
      }

      // aplica buffs a mobs (strength/resistance 20s equivalente)
      applyMobBuffsFromSources(sourcesByPhase);

      // propaga tags de fase a jugadores cercanos (prioridad 4>3>2>1)
      propagatePhaseTagsToPlayers(sourcesByPhase);
    }, INTERVAL);
  });
});
