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

// =======================================
// CONFIGURAÇÕES
// =======================================
const ARENA_MIN = { x: 6987, y: 218, z: 7010 };
const ARENA_MAX = { x: 7015, y: 222, z: 7050 };
const ABANDON_MIN = { x: ARENA_MIN.x - 40, y: ARENA_MIN.y - 60, z: ARENA_MIN.z - 40 };
const ABANDON_MAX = { x: ARENA_MAX.x + 40, y: ARENA_MAX.y + 100, z: ARENA_MAX.z + 40 };
const LOBBY = { x: 41, y: 70, z: 36 };
const ARENA_TAG = "arena";
const LOOT_TABLE = "loot loot_aleatorios_arena";
const KIT_LOOT_TABLE = "kit_arena";
const COMBAT_DURATION_SECONDS = 200; // 6 minutos
const GRACE_SECONDS = 15;

// =======================================
// UTIL
// =======================================
const TICKS_PER_SECOND = 20;
const rand = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
const randomArenaPos = () => ({
  x: rand(ARENA_MIN.x, ARENA_MAX.x),
  y: ARENA_MIN.y,
  z: rand(ARENA_MIN.z, ARENA_MAX.z)
});
const insideXZ = (pos, min, max) =>
  pos.x >= min.x && pos.x <= max.x && pos.z >= min.z && pos.z <= max.z;
const insideBox = (pos, min, max) =>
  pos.x >= min.x && pos.x <= max.x &&
  pos.y >= min.y && pos.y <= max.y &&
  pos.z >= min.z && pos.z <= max.z;
function setArenaSpawnPoint(player) {
  const p = randomArenaPos();
  try { player.runCommand(`spawnpoint @s ${p.x} ${p.y} ${p.z}`); } catch {}
}

// =======================================
// ESTADO
// =======================================
let combatActive = false;
let combatTicksLeft = 0;
let timeLoopHandle = undefined;
let hudLoopHandle = undefined;
let lootLoopHandle = undefined;
const graceStartTick = new Map();
const kitGivenThisBattle = new Set(); // ← jogadores que já receberam kit nesta batalha

// =======================================
// DÁ O KIT SÓ UMA VEZ POR BATALHA
// =======================================
function giveKit(player) {
  if (kitGivenThisBattle.has(player.id)) return; // já recebeu nesta batalha

  try {
    player.runCommand(`loot give @s loot ${KIT_LOOT_TABLE}`);
    kitGivenThisBattle.add(player.id);
  } catch (e) {
    player.sendMessage("§cErro ao dar o kit da arena!");
  }
}

// =======================================
// ENTRADA NA ARENA (dá kit só uma vez por batalha)
// =======================================
system.runInterval(() => {
  if (!combatActive) {
    const anyInside = world.getPlayers().some(p => insideXZ(p.location, ARENA_MIN, ARENA_MAX));
    if (anyInside) startCombat();
    return;
  }

  world.getPlayers().forEach(p => {
    if (p.hasTag(ARENA_TAG)) return;
    if (!insideXZ(p.location, ARENA_MIN, ARENA_MAX)) return;

    p.addTag(ARENA_TAG);
    giveKit(p); // kit só uma vez por batalha

    const tp = randomArenaPos();
    try {
      p.teleport(tp);
      setArenaSpawnPoint(p);
      p.runCommand(`playsound minecraft:entity.wither.spawn @s`);
      p.runCommand(`titleraw @s title {"rawtext":[{"translate":"arena.entrada"}]}`);
    } catch {}
  });
}, 10);

// =======================================
// RESPAWN: NÃO DÁ KIT NOVO
// =======================================
world.afterEvents.playerSpawn.subscribe(evt => {
  const p = evt.player;
  if (!combatActive || !p.hasTag(ARENA_TAG)) return;

  system.runTimeout(() => {
    const tp = randomArenaPos();
    try {
      p.teleport(tp);
      setArenaSpawnPoint(p);
    } catch {}
  }, 10);
});

// =======================================
// KILLS
// =======================================
world.afterEvents.entityDie.subscribe(evt => {
  const dead = evt.deadEntity;
  const killer = evt.damageSource?.damagingEntity;

  if (dead.typeId !== "minecraft:player" || !dead.hasTag(ARENA_TAG)) return;
  if (!killer || killer.typeId !== "minecraft:player" || !killer.hasTag(ARENA_TAG) || killer.id === dead.id) return;

  const obj = world.scoreboard.getObjective("kills_arena");
  if (!obj) return;
  const current = obj.getScore(killer) ?? 0;
  obj.setScore(killer, current + 1);

  world.getPlayers({ tags: [ARENA_TAG] }).forEach(p => {
    try {
      p.runCommand(`tellraw @s {"rawtext":[{"text":"§c☠ ${killer.name} §7matou §c${dead.name}§7! (§e${current + 1} kills§7)"}]}`);
      p.runCommand(`playsound random.orb @s ~ ~ ~ 1 1.2`);
    } catch {}
  });
});

// =======================================
// ABANDONO + PUNIÇÃO
// =======================================
system.runInterval(() => {
  if (!combatActive) { graceStartTick.clear(); return; }
  const now = system.currentTick;

  world.getPlayers({ tags: [ARENA_TAG] }).forEach(player => {
    const pos = player.location;
    const dentroTolerancia = insideBox(pos, ABANDON_MIN, ABANDON_MAX);
    const dentroArena = insideXZ(pos, ARENA_MIN, ARENA_MAX);

    if (dentroArena && graceStartTick.has(player.id)) {
      graceStartTick.delete(player.id);
      try { player.runCommand(`title @s actionbar {"rawtext":[{"translate":"voltou.arena"}]}`); } catch {}
    }

    if (!dentroTolerancia && !graceStartTick.has(player.id)) {
      graceStartTick.set(player.id, now);
      try {
        player.runCommand(`titleraw @s title {"rawtext":[{"translate":"volte.ja"}]}`);
        player.runCommand(`titleraw @s subtitle {"rawtext":[{"text":"§f${GRACE_SECONDS}s ou será PUNIDO!"}]}`);
        player.runCommand(`playsound random.orb @s ~ ~ ~ 2 0.8`);
      } catch {}
    }

    const start = graceStartTick.get(player.id);
    if (start != null) {
      const elapsed = now - start;
      const secsLeft = Math.max(0, Math.ceil((GRACE_SECONDS * TICKS_PER_SECOND - elapsed) / TICKS_PER_SECOND));
      try {
        player.runCommand(`titleraw @s actionbar {"rawtext":[{"text":"§cVolte em §l${secsLeft}s §r§csenão perde tudo!"}]}`);
        if (secsLeft <= 5) player.runCommand(`playsound note.bass @s ~ ~ ~ 2 0.5`);
      } catch {}
      if (elapsed >= GRACE_SECONDS * TICKS_PER_SECOND) {
        punishAbandon(player);
      }
    }
  });
}, 10);

function punishAbandon(player) {
  const obj = world.scoreboard.getObjective("kills_arena");
  world.getPlayers({ tags: [ARENA_TAG] }).forEach(p => {
    try {
      p.runCommand(`tellraw @s {"rawtext":[{"text":"§c⚠ ${player.name} foi PUNIDO por abandono! (kills zerados)"}]}`);
      p.runCommand(`playsound entity.wither.shoot @s`);
    } catch {}
  });

  try { if (obj) obj.setScore(player, 0); player.stopSound("floresta_mistica"); } catch {}

  try {
    player.runCommand(`spawnpoint @s ${LOBBY.x} ${LOBBY.y} ${LOBBY.z}`);
    player.teleport(LOBBY);
  } catch {}

  player.removeTag(ARENA_TAG);
  graceStartTick.delete(player.id);
  kitGivenThisBattle.delete(player.id); // permite kit novo na próxima entrada

  try {
    player.runCommand(`titleraw @s title {"rawtext":[{"translate":"punido.title.combat"}]}`);
    player.runCommand(`titleraw @s subtitle {"rawtext":[{"text":"§7Kills zerados + expulso da arena"}]}`);
    player.runCommand(`playsound entity.generic.explode @s`);
  } catch {}
}

// =======================================
// COMBATE (tempo em tempo real)
// =======================================
function startCombat() {
  if (combatActive) return;
  combatActive = true;
  combatTicksLeft = COMBAT_DURATION_SECONDS * TICKS_PER_SECOND;

  const obj = world.scoreboard.getObjective("kills_arena");
  if (obj) world.getPlayers().forEach(p => { try { obj.setScore(p, 0); } catch {} });

  kitGivenThisBattle.clear(); // nova batalha = todos podem receber kit novo

  world.getPlayers().forEach(p => {
    if (!insideXZ(p.location, ARENA_MIN, ARENA_MAX)) return;
    p.addTag(ARENA_TAG);
    giveKit(p); // kit na entrada da batalha
    const tp = randomArenaPos();
    try { p.teleport(tp); setArenaSpawnPoint(p); } catch {}
  });

  world.getPlayers({ tags: [ARENA_TAG] }).forEach(p => {
    try {
      p.runCommand(`playsound minecraft:entity.wither.spawn @s`);
      p.runCommand(`playsound horda @a[tag=${ARENA_TAG}]`);
      p.runCommand(`titleraw @s title {"rawtext":[{"translate":"start.battle.arena.msg"}]}`);
    } catch {}
  });

  lootLoopHandle = system.runInterval(() => {
    if (!combatActive) return;
    const pos = randomArenaPos();
    try {
      world.getDimension("overworld").runCommand(`loot spawn ${pos.x} ${pos.y} ${pos.z} ${LOOT_TABLE}`);
    } catch {}
  }, 300);

  timeLoopHandle = system.runInterval(() => {
    if (!combatActive || combatTicksLeft <= 0) return;
    combatTicksLeft--;
    if (combatTicksLeft <= 0) finishCombat();
  }, 1);

  hudLoopHandle = system.runInterval(() => {
    if (!combatActive) return;
    const players = world.getPlayers({ tags: [ARENA_TAG] });
    if (players.length === 0) return;

    const secondsLeft = Math.floor(combatTicksLeft / TICKS_PER_SECOND);
    let msg = `§cTempo: ${secondsLeft}s §8| §aKills:\n`;
    players.forEach(p => {
      const kills = world.scoreboard.getObjective("kills_arena")?.getScore(p) ?? 0;
      msg += `§f${p.name}: §a${kills} kills\n`;
    });
    players.forEach(p => {
      try { p.runCommand(`titleraw @s actionbar {"rawtext":[{"text":"${msg}"}]}`); } catch {}
    });
  }, 20);
}

function finishCombat() {
  const players = world.getPlayers({ tags: [ARENA_TAG] });
  const obj = world.scoreboard.getObjective("kills_arena");
  const board = players.map(p => ({ name: p.name, kills: obj?.getScore(p) ?? 0 }))
                       .sort((a, b) => b.kills - a.kills);
  const winner = board.length > 0 && (board.length === 1 || board[0].kills > board[1].kills) ? board[0] : null;

  players.forEach(p => {
    try { p.runCommand(`stopsound @s horda`); } catch {}
    if (winner) {
      try {
        p.runCommand(`playsound random.levelup @s`);
        p.runCommand(`titleraw @s title {"rawtext":[{"translate":"§a§lVENCEDOR: §e${winner.name}"}]}`);
        p.runCommand(`titleraw @s subtitle {"rawtext":[{"text":"§a${winner.kills} kills!"}]}`);
      } catch {}
    } else {
      try {
        p.runCommand(`playsound random.burp @s`);
        p.runCommand(`titleraw @s title {"rawtext":[{"translate":"empate.arena"}]}`);
      } catch {}
    }
    try {
      p.runCommand(`spawnpoint @s ${LOBBY.x} ${LOBBY.y} ${LOBBY.z}`);
      p.teleport(LOBBY);
    } catch {}
    p.removeTag(ARENA_TAG);
  });

  try {
    world.getDimension("overworld").runCommand(
      `kill @e[type=item,x=${ARENA_MIN.x},y=${ARENA_MIN.y},z=${ARENA_MIN.z},dx=${ARENA_MAX.x - ARENA_MIN.x},dy=50,dz=${ARENA_MAX.z - ARENA_MIN.z}]`
    );
  } catch {}

  kitGivenThisBattle.clear(); // próxima batalha pode receber kit novo
  stopCombat();
}

function stopCombat() {
  combatActive = false;
  graceStartTick.clear();
  if (timeLoopHandle) { system.clearRun(timeLoopHandle); timeLoopHandle = undefined; }
  if (hudLoopHandle) { system.clearRun(hudLoopHandle); hudLoopHandle = undefined; }
  if (lootLoopHandle) { system.clearRun(lootLoopHandle); lootLoopHandle = undefined; }
}

// =======================================
// VERIFICA SE O ITEM TEM A LORE "Arena Itens"
// =======================================
function hasArenaLore(item) {
  if (!item) return false;
  try {
    const lore = item.getLore();
    return lore.some(line => line.includes("Arena Itens"));
  } catch (e) {
    return false;
  }
}

// =======================================
// REMOVE ITENS DA ARENA (inventário + offhand + armadura)
// =======================================
function removeArenaItemsFromPlayer(player) {
  if (player.hasTag("arena")) return; // quem tá na arena pode ter os itens

  let removed = 0;

  // 1. Inventário normal (hotbar + slots principais)
  const inventory = player.getComponent("inventory")?.container;
  if (inventory) {
    for (let i = 0; i < inventory.size; i++) {
      const item = inventory.getItem(i);
      if (hasArenaLore(item)) {
        inventory.setItem(i, null);
        removed++;
      }
    }
  }

  // 2. Mão esquerda (offhand)
  const offhand = player.getComponent("equippable")?.getEquipment("Offhand");
  if (offhand && hasArenaLore(offhand)) {
    player.getComponent("equippable")?.setEquipment("Offhand", null);
    removed++;
  }

  // 3. Armadura (capacete, peitoral, calça, botas)
  const equippable = player.getComponent("equippable");
  if (equippable) {
    const armorSlots = ["Head", "Chest", "Legs", "Feet"];
    armorSlots.forEach(slot => {
      const armor = equippable.getEquipment(slot);
      if (armor && hasArenaLore(armor)) {
        equippable.setEquipment(slot, null);
        removed++;
      }
    });
  }

  // Mensagem opcional (descomenta se quiser ver quando remove)
  // if (removed > 0) {
  //   player.sendMessage(`§c[Arena] ${removed} item(s) proibido(s) removido(s)!`);
  // }
}

// =======================================
// 1. Remove ao respawnar / entrar no mundo
// =======================================
world.afterEvents.playerSpawn.subscribe((ev) => {
  system.runTimeout(() => removeArenaItemsFromPlayer(ev.player), 20);
});

// =======================================
// 2. Checagem constante (a cada 2 segundos)
// =======================================
system.runInterval(() => {
  for (const player of world.getPlayers()) {
    removeArenaItemsFromPlayer(player);
  }
}, 40); // 40 ticks = 2 segundos
